php-newbie: Fehler in Sticky Form

Hallo allerseits!

Ich bin grad dabei PHP zu büffeln. Als Hilfe hab ich mir das angeblich einfache Buch "PHP & MySQL von Kopf bis Fuss". Das ist soweit auch ganz gut (ausser dass die Autoren bis zum Kapitel 4 mindestens schon 20 Semikolon und Klammerfehler gemacht haben). Nun bin ich aber bei einem Affenformular und raff da irgendwas nicht (oder es ist ein Fehler der Autoren).

Hier das fertige Formular (ohne CSS) wie es für das Buch zur Verfügung steht.

  
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">  
<head>  
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
  <title>Mach mich Elvis - E-Mail senden</title>  
  <link rel="stylesheet" type="text/css" href="style.css" />  
</head>  
<body>  
  <img src="blankface.jpg" width="161" height="350" alt="" style="position: absolute;left:380px" />  
  <img name="elvislogo" src="elvislogo.gif" width="257" height="32" border="0" alt="Mach Mich Elvis" />  
  <p><strong>Privat:</strong> NUR zu Elmars Verwendung!<br />  
  Eine E-Mail schreiben und an alle auf der Liste versenden.</p>  
  
<?php  
  if (isset($_POST['submit'])) {  
      $von = 'elmar@machmichelvis.com';  
	  $betreff = $_POST['betreff'];  
	  $text = $_POST['elvismail'];  
	  $form_ausgeben = false;  
	  
	  if (empty($betreff) && empty($text)) {  
	    // $betreff UND $text müssen leer sein  
	    echo 'Sie haben Betreff und Inhalt vergessen.<br />';  
	    $form_ausgeben = true;  
	  }  
	  
	  if (empty($betreff) && (!empty($text))) {  
	    echo 'Sie haben den Betreff vergessen.<br />';  
	    $form_ausgeben = true;  
	  }  
	  
	  if ((!empty($betreff)) && empty($text)) {  
	    echo 'Sie haben den Inhalt vergessen.<br />';  
	    $form_ausgeben = true;  
	  }  
	  
	  if ((!empty($betreff)) && (!empty($text))) {  
		  // Alles in Ordnung, Mails senden  
		  $db = mysqli_connect('localhost', 'elmar', 'derking', 'elvis_laden')  
		    or die('Fehler beim Verbinden mit MySQL-Server.');  
		  mysqli_set_charset($db, "utf8");  
		  
		  $sql = "SELECT * FROM email_liste";  
		  $ergebnis = mysqli_query($db, $sql)  
		    or die('Fehler bei Datenbankabfrage.');  
		  
		  while ($zeile = mysqli_fetch_array($ergebnis)) {  
		    $an = $zeile['email'];  
		    $vorname = $zeile['vorname'];  
		    $nachname = $zeile['nachname'];  
		    $msg = "Liebe(r) $vorname $nachname,\n$text";  
		    mail($an, $betreff, $msg, 'From:' . $von);  
		    echo 'Gemailt an: ' . $an . '<br />';  
		  }  
	  	mysqli_close($db);  
	  }  
  }  
  else {  
    $form_ausgeben = true;  
  }  
  
  if ($form_ausgeben) {  
?>  
  
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">  
  <label for="betreff">Betreff:</label><br />  
  <input id="betreff" name="betreff" type="text" size="30"  
    value="<?php echo $betreff; ?>"/><br />  
  <label for="elvismail">E-Mail-Inhalt:</label><br />  
  <textarea id="elvismail" name="elvismail" rows="8" cols="40">  
     <?php echo $text; ?></textarea><br />  
  <input type="submit" name="submit" value="Senden" />  
</form>  
<?php  
  }  
?>  
</body>  
</html>  

Wenn ich nun die Seite lade, dann erscheint in den Formularfelder eine Fehlermeldung, dass jeweils die Variable $text und $betreff nicht definiert seien. Das macht meiner Meinung nach auch Sinn, da die Variablen ja nur definiert werden, wenn $_POST['submit'] gesetzt ist. Richtig?

Wenn meine Annahme stimmt, ist das also ein Fehler im Buch. Aber wie müsst ich denn das nun lösen, dass keine Fehlermeldung beim ersten laden erscheint?

Einfach unter

  
  else {  
    $form_ausgeben = true;  

nochmals die variablen definieren... sprich:

  
    $betreff = $_POST['betreff'];  
    $text = $_POST['elvismail'];  

Korrekt?

Danke schonmal für eure Hilfe!

Mike

  1. Ähm.. ich nochmal. Ich glaub ich muss die Frage noch ein bisschen umformulieren. Funktionieren tuts ja so wie ichs vorgeschlagen habe. Die Frage ist eher, ist das programmiertechnisch sauber oder gibts eine schönere Lösung.

    Weil im Buch steht, man solle vermeiden etwas doppelt zu schreiben. Mit meiner Lösung würde ich ja aber die beiden Variablen doppelt schreiben. Gibts eine schönere Lösung?

    Danke ;)

  2. Hi,

    [code lang=php]  if (isset($_POST['submit'])) {
          $von = 'elmar@machmichelvis.com';
      $betreff = $_POST['betreff'];
      $text = $_POST['elvismail'];
      $form_ausgeben = false;

    if (empty($betreff) && empty($text)) {
        // $betreff UND $text müssen leer sein

    Wenn ich nun die Seite lade, dann erscheint in den Formularfelder eine Fehlermeldung, dass jeweils die Variable $text und $betreff nicht definiert seien. Das macht meiner Meinung nach auch Sinn, da die Variablen ja nur definiert werden, wenn $_POST['submit'] gesetzt ist. Richtig?

    Richtig.

    Wenn meine Annahme stimmt, ist das also ein Fehler im Buch. Aber wie müsst ich denn das nun lösen, dass keine Fehlermeldung beim ersten laden erscheint?

    Die Abfrage, ob die entsprechenden Einträge gesetzt sind, kann man mittels isset/empty machen.
    Macht das Script auch - aber an der falschen Stelle und zu spät.

    Ausserdem ist das umkopieren von POST/GET-Werten in andere Variablen eine Unsitte. Man kann ruhig mit $_POST/$_GET arbeiten, da spricht nichts dagegen - aber dafür, dass man immer auf einen Blick erkennt, wo die Werte eigentlich herkommen.

    MfG ChrisB

    --
    “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
    1. Hi Chris!

      Erstmal Dankeschön!

      Die Abfrage, ob die entsprechenden Einträge gesetzt sind, kann man mittels isset/empty machen.
      Macht das Script auch - aber an der falschen Stelle und zu spät.

      Wo wärs denn korrekt?

      Klingt nicht so als wär das Buch gut. Ok.. ist erst Kapitel 4, vielleicht räumen die noch bisschen auf mit dem Code, aber ist schon frustrierend, dass ich hier gleich so ernüchternde Feedbacks bekomme. Da strebt die Motivation weiterzumachen gleich gegen Null. Und Reue kommt auf, relativ viel Geld für das Buch ausgegeben zu haben ;(

      Gruss

  3. Hello,

    von sauberer = durchschaubarer Strukturierung haben die Autoren aber bestimmt noch nichts gehört. Der Aufbau (die Staffelung) der Bedingungskonstrukte schreit nach einer vernünftigen Planung!

    Liebe Grüße aus dem schönen Oberharz

    Tom vom Berg

    --
     ☻_
    /▌
    / \ Nur selber lernen macht schlau
    http://bergpost.annerschbarrich.de
    1. Hallo Tom

      von sauberer = durchschaubarer Strukturierung haben die Autoren aber bestimmt noch nichts gehört. Der Aufbau (die Staffelung) der Bedingungskonstrukte schreit nach einer vernünftigen Planung!

      Hmm... vielleicht verbessert sich noch im laufe des Buches. Es ist ziemlich Schritt für Schritt aufgebaut. Es werden auch Konstrukte gezeigt die nicht gut sind um dann aufzuzeigen, wieso diese Vorgehen nicht gut sind und wie mans besser macht.

      Nimm mir nicht die Hoffnung und sag mir lieber wies besser geht ;)

      Danke und Gruss

  4. Hi!

    Ich bin grad dabei PHP zu büffeln. Als Hilfe hab ich mir das angeblich einfache Buch "PHP & MySQL von Kopf bis Fuss". Das ist soweit auch ganz gut (ausser dass die Autoren bis zum Kapitel 4 mindestens schon 20 Semikolon und Klammerfehler gemacht haben).

    Ein Buch, dass PHP lehren möchte und nicht nur solche kleinen Fehler bringt sondern auch noch konzeptionelle ist in meinen Augen klar ein Sachmangel und somit reklamierbar. Eine Beseitungung der Fehler wird wohl der Händler nicht vornehmen (lassen) können, also bleibt nur die Rückgabe mit Kaufpreiserstattung. Die gleichen Fehler kannst du auch ohne Geld auszugeben in Anfängertutorials im Netz bekommen.

    Nun bin ich aber bei einem Affenformular und raff da irgendwas nicht (oder es ist ein Fehler der Autoren).

    Mehrere.

    $von = 'elmar@machmichelvis.com';

    Das Script soll ein Beispiel sein. Auch wenn dem Autor die Domain gehören sollte, wäre es besser, dem Anfänger das Verwenden der für Beispiele vorgesehehen Domainnamen beizubringen.

    $betreff = $_POST['betreff'];
      $text = $_POST['elvismail'];

    Das sinnlose Umkopieren ist anscheinend nicht totzukriegen.

        // Alles in Ordnung, Mails senden  
        $db = mysqli\_connect('localhost', 'elmar', 'derking', 'elvis\_laden')  
          or die('Fehler beim Verbinden mit MySQL-Server.');  
    

    or die() ist kurz und schmerzlos aber eine ganz schlechte Praxis. Zum einen bleibt durch das Sterbenlassen ein unvollständiges HTML-Dokument übrig. Zum anderen nützt das Sterbenlassen dem Anwender, der die Seite zu Gesicht bekommt, überhaupt nichts. Der kann weder was für den Fehler, er kann ihn auch nicht beseitigen und dass der MySQL-Server nicht funktioniert geht ihn gleich gar nichts an. Du als Administrator hingegen wirst von dem Fehlverhalten nicht informiert, wenn nicht gerade einer der Kunden so nett ist, dir eine Nachricht zu senden, bevor er bei der Konkurrenz einkaufen geht.

    Hier wäre zu überlegen, wie im Fehlerfall dem Anwender geholfen ist, so dass er sein Anliegen auf alternative Weise los wird. Das muss so gestaltet werden, dass zum einen ein vollständiges HTML-Dokument entsteht, zum anderen du trotz des Fehlverhaltens noch an die Daten kommst, und du außerdem über den Fehler informiert wirst.

        mysqli\_set\_charset($db, "utf8");  
    

    Na immerhin haben die Autoren schonmal was von Zeichenkodierung gehört.

          $an = $zeile['email'];  
          $vorname = $zeile['vorname'];  
          $nachname = $zeile['nachname'];  
    

    Wieder sinnloses Umkopieren.

    <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">

    Das unbehandelte Einfügen von $_SERVER['PHP_SELF'] ist ebenso wie ...

    <input id="betreff" name="betreff" type="text" size="30"
        value="<?php echo $betreff; ?>"/><br />
      <textarea id="elvismail" name="elvismail" rows="8" cols="40">
         <?php echo $text; ?></textarea><br />

    ... bei Betreff und Text eine der am häufigsten vorkommenden Sicherheitslücken, da der Kontextwechsel nicht beachtet wurde.

    Beim Aufruf der Seite können nämlich Parameter (?foo=bar) angehängt werden, die in $_SERVER['PHP_SELF'] landen. Wenn man da geschickt Werte einfügt, kann man das action-Attribut mit einem " beenden und dann beliebigen HTML-Code (inklusive Javascript) einschleusen. Ein htmlspecialchars() um $_SERVER['PHP_SELF'] und Betreff und Text ist eine Pflichtveranstaltung.

    Wenn ich nun die Seite lade, dann erscheint in den Formularfelder eine Fehlermeldung, dass jeweils die Variable $text und $betreff nicht definiert seien.

    Dann hast du im Gegensatz zu den Autoren das error_reporting auf E_ALL stehen und erkennst solche Zugriffe auf nicht initialisierte Variablen.

    Das macht meiner Meinung nach auch Sinn, da die Variablen ja nur definiert werden, wenn $_POST['submit'] gesetzt ist. Richtig?

    Genau.

    Aber wie müsst ich denn das nun lösen, dass keine Fehlermeldung beim ersten laden erscheint?

    Achte immer darauf, dass Variablen in allen Lebenslagen initialisiert werden. Das heißt, dass sie entweder vor einem if oder sowohl in if als auch else angelegt werden. Alternativ muss beim lesenden Verwenden ihr Vorhandensein mit isset() oder auch empty() geprüft werden.

    Lern das Affenformular lieber mit dem Wikipedia-Beispiel: http://de.wikipedia.org/wiki/Affenformular oder mit der PHP-FAQ: http://www.php-faq.de/q-stil-normalform.html. Letzteres wäre auch ein allgemein empfehlenswertes Tutorial.

    Lo!

    1. Hi dedlfix!

      Woah! Ok, das war ausführlich. Danke erstmal. Ich wollte das Buch dank Deiner Antwort nun schon frustriert wegschmeissen und die ganze Geschichte aufgeben...

      AAABBBERRR!!! Ich muss wohl nochmals anmerken: Ich bin erst in Kapitel 4 des Buches. Ich hab mal nach hinten geblättert und in Kapitel 6 kommt ein Abschnitt wo es drum geht meine Daten gegen SQL-Injections zu wappnen und noch weiter hinten kommen weitere "sicherheitsthemen". Ich denke so schlecht ists doch nicht. Es baut einfach Schritt für Schritt auf. Und zwar in wirklich kleinen Schritten, sodass auch Idioten wie ich mitkommen.

      Ich denke Dinge wie "or die" werden einfach mal so in den Raum geschmissen um erste simple (wenn auch fehlerhafte) Anwendungen aufzubauen und werden zu gegebener Zeit wieder aufgegriffen und dann aufgezeigt wie mans "richtig" macht. Wenn alles gleich zu beginn erklärt werden würde (wie jetzt von Dir ;) ), wäre ich sofort hoffnungslos überfordet.

      Ich schätze mal ich mach einfach weiter und hoffe, dass es nicht für die Katz war. Den Link zur php-faq hab ich mir gespeichert und werde sicher auch das noch durchgehen, nachdem ich die Idioteneinführung absolviert habe. Danke dafür!

      Ach... noch zum Umkopieren der $_POST-Werten. Im Buch wurde das mit der Begründung gemacht, dass die eigenen Variablen einfacher zu bearbeiten bzw. verwenden sind. Da muss ich sagen seh ich das schon bisschen so wie das Buch. Ich bin zwar schnell im tippen, aber solche Fingerbrecher wie $_POST['wasauchimmer'] mehrmals zu schreiben würde mich echt ankotzen. Und ich bin auch schneller im tippen von $wasauchimmer, als die "POST-Version" zu markieren und kopieren. Von daher... schaden tut das Umkopieren ja nicht, oder doch?

      Gruss
      Mike

      1. Hi!

        AAABBBERRR!!! Ich muss wohl nochmals anmerken: Ich bin erst in Kapitel 4 des Buches. Ich hab mal nach hinten geblättert und in Kapitel 6 kommt ein Abschnitt wo es drum geht meine Daten gegen SQL-Injections zu wappnen und noch weiter hinten kommen weitere "sicherheitsthemen". Ich denke so schlecht ists doch nicht. Es baut einfach Schritt für Schritt auf. Und zwar in wirklich kleinen Schritten, sodass auch Idioten wie ich mitkommen.

        Bewusst etwas falsch zu machen sollte zeigen, was für ein Problem dabei entsteht. Es erst einmal stillschweigend falsch zu machen, halte ich nicht für den richtigen Weg. Kontextwechsel zu beachten ist so ein wichtiges Sicherheitsthema, dass der Lernwillige gleich von Anfang an darauf sensibilisert werden sollte.

        Ich denke Dinge wie "or die" werden einfach mal so in den Raum geschmissen um erste simple (wenn auch fehlerhafte) Anwendungen aufzubauen und werden zu gegebener Zeit wieder aufgegriffen und dann aufgezeigt wie mans "richtig" macht. Wenn alles gleich zu beginn erklärt werden würde (wie jetzt von Dir ;) ), wäre ich sofort hoffnungslos überfordet.

        Später zu reparieren fördert eine lasche Einstellung zu den Dingen. Es darf nicht erst einmal falsch gemacht werden und hinterher, wenn Zeit ist oder mit anderer Ausrede, werden die Sicherheitslücken gefixt.

        Ach... noch zum Umkopieren der $_POST-Werten. Im Buch wurde das mit der Begründung gemacht, dass die eigenen Variablen einfacher zu bearbeiten bzw. verwenden sind. Da muss ich sagen seh ich das schon bisschen so wie das Buch. Ich bin zwar schnell im tippen, aber solche Fingerbrecher wie $_POST['wasauchimmer'] mehrmals zu schreiben würde mich echt ankotzen. Und ich bin auch schneller im tippen von $wasauchimmer, als die "POST-Version" zu markieren und kopieren. Von daher... schaden tut das Umkopieren ja nicht, oder doch?

        Der Kontextwechsel muss zwar immer und nicht nur bei Eingabewerten berücksichtigt werden, weswegen eine Verschleierung der Herkunft eigentlich nichts ausmachen dürfte. Aber trotzdem erhöht sich die Komplexität durch weitere Variablen. Beim Analysieren eines fremden Scripts muss man nun immer im Hinterkopf behalten, was das für Variablen sind. Einem $_POST sieht man das sofort an. Und das bisschen Mehraufwand beim Tippen sollte zugunsten der Klarheit in Kauf genommen werden.

        Lo!

      2. Moin!

        Ach... noch zum Umkopieren der $_POST-Werten. Im Buch wurde das mit der Begründung gemacht, dass die eigenen Variablen einfacher zu bearbeiten bzw. verwenden sind. Da muss ich sagen seh ich das schon bisschen so wie das Buch. Ich bin zwar schnell im tippen, aber solche Fingerbrecher wie $_POST['wasauchimmer'] mehrmals zu schreiben würde mich echt ankotzen. Und ich bin auch schneller im tippen von $wasauchimmer, als die "POST-Version" zu markieren und kopieren. Von daher... schaden tut das Umkopieren ja nicht, oder doch?

        Jein. Im Regelfall ist die Datenmenge zu gering, das lässt also Performanceprobleme nicht so dringend vermuten.

        ABER:

        In Perl gibt einen Taint-Modus.  In diesem verweigert Perl Daten aus unsicheren Quellen z.B. in System-Aufrufen zu verwenden ohne dass diese behandelt wurden.

        In PHP vermisse ich dies (schreibt mir wo und wie, wenn es das gibt...)

        Wenn Daten in $_POST, $_GET, $_REQUEST, $_COOKIE, stehen, dann weiß ich: Dies sind Nutzereingaben, also potentiell vergiftet und ich muss (mindestens) diese vor der Verwendung behandeln um schädliche Handlungen irgendwelcher Benutzer zu verhindern.

        Durch technisch sinnlose Umkopieren entziehe ich mir die Möglichkeit dies auf den ersten Blick zu erkennen. Und alles wegen ein wenig Schreibarbeit, die mir auch der Editor weitgehend abnimmt...

        MFFG (Mit freundlich- friedfertigem Grinsen)

        fastix

        1. Hi!

          Wenn Daten in $_POST, $_GET, $_REQUEST, $_COOKIE, stehen, dann weiß ich: Dies sind Nutzereingaben, also potentiell vergiftet und ich muss (mindestens) diese vor der Verwendung behandeln um schädliche Handlungen irgendwelcher Benutzer zu verhindern.

          Es sind prinzipiell alle Daten zu behandeln. Daten aus einem DBMS wären erst einmal keine Benutzerdaten. Wenn sie früher mal welche waren, sieht man es ihnen auch nicht an. Das "man kann sehen, dass es Benutzerdaten sind und deshalb weiß man, dass sie gefährlich sind" mit der daraus resultierenden Gegenschluss "alles andere ist sicher" wäre ein Trugschluss. Jedes (String-)Datum kann Zeichen enthalten, die in bestimmten Kontexten Sonderbedeutung haben und sollte unabhängig von seiner Herkunft behandelt werden.

          Das Herkunftsargument zieht also nicht, jedenfalls nicht aus Sicherheitsgründen.

          Lo!

          1. Moin!

            Wenn Daten in $_POST, $_GET, $_REQUEST, $_COOKIE, stehen, dann weiß ich: Dies sind Nutzereingaben, also potentiell vergiftet und ich muss (mindestens) diese vor der Verwendung behandeln um schädliche Handlungen irgendwelcher Benutzer zu verhindern.

            Das "man kann sehen, dass es Benutzerdaten sind und deshalb weiß man, dass sie gefährlich sind" mit der daraus resultierenden Gegenschluss "alles andere ist sicher" wäre ein Trugschluss.

            Den Trugschluss habe ich aber ausweislich meiner Formulierung gerade nicht nahe gelegt. Wenn ich behaupte, dass "wenn Daten in $_POST, $_GET, $_REQUEST, $_COOKIE, stehen, diese potentiell vergiftet sind, dann hab ich über andere Variablen gar nichts gesagt. Wie kommst Du dazu mir jeder Logik zu wieder anderes zu unterstellen?

            Es sind prinzipiell alle Daten zu behandeln.

            Wieso sollte ich $datum  behandeln wenn ich es zuvor mit $datum=date('Y-M-D H:i:s'); gefüllt habe?

            MFFG (Mit freundlich- friedfertigem Grinsen)

            fastix

            1. Hi!

              Wenn Daten in $_POST, $_GET, $_REQUEST, $_COOKIE, stehen, dann weiß ich: Dies sind Nutzereingaben, also potentiell vergiftet und ich muss (mindestens) diese vor der Verwendung behandeln um schädliche Handlungen irgendwelcher Benutzer zu verhindern.

              Das "man kann sehen, dass es Benutzerdaten sind und deshalb weiß man, dass sie gefährlich sind" mit der daraus resultierenden Gegenschluss "alles andere ist sicher" wäre ein Trugschluss.

              Den Trugschluss habe ich aber ausweislich meiner Formulierung gerade nicht nahe gelegt. Wenn ich behaupte, dass "wenn Daten in $_POST, $_GET, $_REQUEST, $_COOKIE, stehen, diese potentiell vergiftet sind, dann hab ich über andere Variablen gar nichts gesagt. Wie kommst Du dazu mir jeder Logik zu wieder anderes zu unterstellen?

              Du erwähnst explizit die Benutzereingaben, die man besonders vorsichtig behandeln muss. Das lässt den Schluss nahe, dass es Daten geben muss, die nicht so kritisch beachtet werden müssen. Die gibt es aber nicht. Welchen Grund sollte sonst die gesonderte Erwähnung haben? Alle Arten von Daten sind kontextgerecht zu behandeln. Benutzerdaten sind also keine Ausnahme, sie müssen nicht gesondert behandelt werden, nur kontextgerecht.

              Es sind prinzipiell alle Daten zu behandeln.
              Wieso sollte ich $datum  behandeln wenn ich es zuvor mit $datum=date('Y-M-D H:i:s'); gefüllt habe?

              Behandelt werden sollten Daten stets zuerst im Kopf. Was habe ich für Daten? Wo füge ich sie ein? Was muss dabei beachtet werden? Und in dem Sinne solltest du auch mit selbst erzeugten Daten verfahren.

              Lo!

    2. Eine Frage hätte ich da noch:

      <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">

      Das unbehandelte Einfügen von $_SERVER['PHP_SELF'] ist ebenso wie ...

      ...

      ... bei Betreff und Text eine der am häufigsten vorkommenden Sicherheitslücken, da der Kontextwechsel nicht beachtet wurde.

      Beim Aufruf der Seite können nämlich Parameter (?foo=bar) angehängt werden, die in $_SERVER['PHP_SELF'] landen. Wenn man da geschickt Werte einfügt, kann man das action-Attribut mit einem " beenden und dann beliebigen HTML-Code (inklusive Javascript) einschleusen. Ein htmlspecialchars() um $_SERVER['PHP_SELF'] und Betreff und Text ist eine Pflichtveranstaltung.

      Ok, ich versteh kaum ein Wort davon, aber in dem von Dir vermeintlich guten FAQ (http://www.php-faq.de/q-stil-normalform.html) macht das ja auch ohne irgend eine Form der Bearbeitung von $_SERVER['PHP_SELF']?!

      siehe:

      <form action="<?php echo $_SERVER['PHP_SELF']; ?>">  
      <input type="text"  
             name="textfeld"  
             value="<?php if (isset($_REQUEST['textfeld'])) echo htmlspecialchars($_REQUEST['textfeld']); ?>">  
      <br>  
      <input type="submit"  
             name="do_form_x"  
             value="Ausführen">  
      </form>
      

      Also was denn nun? Ist auch diese Seite Schrott?!

      Ich hab so das Gefühl es gibt kein gescheites Tutorial bei dem man sauberes und sicheres PHP lernen kann. *grummel

      1. Hi!

        Beim Aufruf der Seite können nämlich Parameter (?foo=bar) angehängt werden, die in $_SERVER['PHP_SELF'] landen. Wenn man da geschickt Werte einfügt, kann man das action-Attribut mit einem " beenden und dann beliebigen HTML-Code (inklusive Javascript) einschleusen. Ein htmlspecialchars() um $_SERVER['PHP_SELF'] und Betreff und Text ist eine Pflichtveranstaltung.

        Ok, ich versteh kaum ein Wort davon, aber in dem von Dir vermeintlich guten FAQ (http://www.php-faq.de/q-stil-normalform.html) macht das ja auch ohne irgend eine Form der Bearbeitung von $_SERVER['PHP_SELF']?!

        Schade, ein paar Fehler sind wohl auch dort zu finden. Ich muss mich auch etwas korrigieren, denn PHP_SELF enthält nicht den Querystring. Das macht aber nichts, denn es lässt sich trotzdem missbrauchen. Es gibt ein Feature namens PathInfo. Man ruft eine URL auf /bla/foo.php/bar/qux und wenn foo.php bereits ein Script ist, ruft der Webserver dieses auf. Der Rest ist dann die PathInfo. Die kann man im Script abfragen und gewinnbringend nutzen. PHP_SELF enthält ebenfalls diesen PathInfo-Teil, so dass bei einer URL wie foo.php/">...

        [code lang=php]<form action="<?php echo $_SERVER['PHP_SELF']; ?>">

        ... am Ende <form action="foo.php/">..."> entsteht. Du siehst, dass das "> das action-Attribut und das form-Tag beendet und das ... außerhalb steht. Und nun kann beliebiges HTML, das anstelle des ... steht, vom Browser als solches interpretiert werden. Das darf aber nicht. Ein htmlspecialchars($_SERVER['PHP_SELF']) würde das "> zu &quot;&gt; konvertieren und das action-Attribut bleibt unbeendet.

        Also was denn nun? Ist auch diese Seite Schrott?!

        Hmm, ich hatte sie eigentlich in keiner schlechten Erinnerung, aber Fehler werden sich wohl nie gänzlich vermeiden lassen.

        Ich hab so das Gefühl es gibt kein gescheites Tutorial bei dem man sauberes und sicheres PHP lernen kann. *grummel

        Doch, es gibt Seiten, die darauf eingehen. Aber oftmals werden die Anfängertutorials von Nichtmehr-Anfängern geschrieben in der besten Absicht, ihr eben gelerntes Wissen weiterzugeben. Und das ist dann oft noch lückenhaft. Mir ist leider kein Tutorial bekannt, dass fehlerfrei ist und guten Stil lehrt. (Ich suche aber auch nicht aktiv danach.) Die PHP-FAQ ist jedoch noch ein einigermaßen kompetentes.

        Lo!

        1. Hi!

          Hi dedlfix

          Ich bedanke mich für deine ausführlichen Antworten :) und nehme sie mir zu Herzen.

          Ich mach mal das Buch durch um ein Grundverständnis von PHP zu erlangen, schau mir das von Dir verlinkte tutorial an und mach mich dann auf die Suche mir dann Informationen zu wirklich sauberem und sicherem PHP.

          Liebe Grüsse
          Mike

          1. Hi!

            Ich mach mal das Buch durch um ein Grundverständnis von PHP zu erlangen, schau mir das von Dir verlinkte tutorial an und mach mich dann auf die Suche mir dann Informationen zu wirklich sauberem und sicherem PHP.

            Beachte dabei immer: Nicht auf das Wissen, wie man etwas vermeidet kommt es an - das auch, ja - wichtiger ist, zu wissen, warum etwas so ist, wie es ist (also gefährlich oder harmlos und in welchen Situationen).

            mysql_real_escape_string() wäre eine Schutzmaßnahme, aber man darf sich nicht blind darauf verlassen, sonst hat man trotzdem eine Sicherheitslücke: beispielsweise bei Zahlen im MySQL-Statement.

            Lo!