Moin!
ich will in einem php-script mit einer Javascriptfunktion
einen String wieder in ein Formularfeld schreiben, den ich aus einer Datenbank geholt habe.das funktioniert auch wenn im String keine Leerzeichen vorkommen.
Sind Leerzeichen im String,wird garnichts in das Formularfeld geschrieben.was ist hier falsch?
Das kontextgerechte Escaping fehlt bei dir teilweise, und verursacht deine Probleme. Rede von Glück, dass du selbst drauf gestoßen bist, und nicht irgendein böser Angreifer.
die php zeilen:
echo"<input id='song' name='song' class='mytextinput' value='".htmlentities($_POST['song'],ENT_QUOTES)."'/>";
Hier ist Escaping vorhanden, der Kontext ist "Baue eine Variable in einen HTML-String ein". htmlentities() ist dafür im Prinzip auch nutzbar - vernünftiger wäre es, einfach nur htmlspecialchars() zu verwenden, denn Entities sind in den allermeisten Fällen nicht notwendig.
abspeichrn in Datenbank:
$sql = "UPDATE titel SET song = '".mysql_real_escape_string($_POST['song'])."' WHERE tid ='".$_POST['tid']."';";
Hier ist Escaping teilweise vorhanden. Der Kontext ist "Baue eine Variable in einen SQL-String ein", und für $_POST['song'] wird das gemacht - für $_POST['tid'] NICHT! BÖSE FALLE!
link anklicken und in Formularfeld schreiben:
echo "<td><a href='#' onclick=javascript:updatesong('".$dsatz['song']."','".$dsatz['tid']."');>
".$dsatz['song']."</a></td>";
Hier wird es jetzt richtig komplex, denn es gibt im Onclick-Attribut einen verschachtelten Kontext: "Baue eine Variable in einen Javascript-String ein, und das Ergebnis dann in HTML."
Du wirst die Anführungsstriche, die den Attributwert begrenzen, vermutlich schon deshalb weggelassen haben, weil diese zwei Kontexte dir reichlich Fehler beschert haben.
Deshalb mal schrittweise:
1. Frage: Wenn ein Javascript-String mit einfachen Anführungszeichen oder doppelten Anführungszeichen begrenzt wird, wie ist dann mit diesen Zeichen zu verfahren, wenn sie innerhalb des Strings auch noch mal vorkommen?
Antwort: Escapen mit einem Backslash. jsvar = "Hallo, \"Welt\"!":
oder jsvar = 'Hallo, \'Welt\'!';
So einen Backslash liefert dir in PHP die Funktion addslashes().
Folglich wäre der erste Schritt in PHP: Baue eine Variable in einen Javascript-String ein.
$onclickatt = "updatesong('".addslashes($dsatz['song'])."','".addslashes($dsatz['tid'])."');";
2. Frage: Wie kommt der Javascript-String jetzt in den HTML-Kontext des Attributs? Klar, mit htmlspecialchars().
Also:
echo "<a href=\"#\" onclick=\"".htmlspecialchars($onclickatt)."\">".htmlspecialchars($dsatz['song'])."</a>";
Beachte: Die Variablen werden immer escaped, wenn sie in einem anderen Sinnzusammenhang benutzt werden. Wenn sie aus der Datenbank kommen, sind sie nur "reiner Text". Solchen reinen Text kann man aber nicht problemlos als Javascript-String benutzen, weil ja genau die Anführungszeichen enthalten sein könnten, die den String auch begrenzen sollen. Deshalb Escaping für den Javascript-Kontext.
Dann der Einbau in HTML: Auch hier können Zeichen, die in "reinem Text" keine Probleme machen, für Ärger sorgen, vornehmlich <, >, & und ". Genau diese Zeichen werden deshalb von htmlspecialchars() entschärft. Noch bevor irgendein Javascript ausgeführt wird, werden die Entschärfungen durch Entities vom Browser wieder dekodiert, so dass das "richtige" Javascript im Attribut steht.
Ich hoffe, ich habe in der Kürze der Zeit keinen Denkfehler eingebaut. Der wichtigste Punkt ist jedenfalls das doppelte Escaping des Javascripts im onclick-Attribut. Hier wird gerne übersehen, dass der "reine Text" eben nicht nur einen Kontext wechselt, sondern gleich zwei.
Wie du an den anderen Antworten siehst: Bis jetzt hat das noch niemand moniert, obwohl fehlendes Escaping schon mal angesprochen wurde, und die Antworter zu den hilfreichen Fachleuten dieses Forums gehören. Nichts für Ungut, Jungs. ;)
- Sven Rautenberg
"Love your nation - respect the others."