schließendes script-tag im String
hammerfranz
- javascript
Hallo Freunde,
kann mir das bitte mal einer erklären?
<html>
<head>
<script type="text/javascript">
alert("wont be alerted");
alert("</script>");
alert("will be written to document");
</script>
</head>
<body>
</body>
</html>
ausgegeben wird:
"); alert("will be written to document");
Ich kann nicht verstehen, warum das schließende script-tag, obwohl es im String steht, alles kaputt macht. Nicht mal das erste alert wird ausgeführt.
Hat jemand dafür eine Erklärung?
Und weiter: Gibt es workarounds oder Maßnahmen, um user-inputs entsprechend zu filter, damit sie, falls sie nach Eingabe irgendwo in die Seite geschrieben werden nicht alles kaputt machen wenn ein "</script>" eingegeben wird !?
Danke und viele Grüße
Franz
Ich kann nicht verstehen, warum das schließende script-tag, obwohl es im String steht, alles kaputt macht. Nicht mal das erste alert wird ausgeführt.
Weil der Parser meint der Skriptblock ist zuende, daher musst du es "maskieren". z.b. so: </script>
Struppi.
Danke.
Aber dann ist das doch ein ziemlich "dummer" Parser oder?
php hat ja zB nicht solche Probleme:
<html>
<body>
<?php
echo "?>";
echo "woohoo";
?>
</body>
</html>
ausgegeben wird korrekterweise:
?>woohoo
Grüße
Franz
Hi!
Aber dann ist das doch ein ziemlich "dummer" Parser oder?
Ja, denn der "dumme Parser" parst HTML. Er wertet den Javascript-Code nicht aus, weil das nicht seine Aufgabe ist, und weiß also nicht, dass er sich in einem Javascript-String befindet. Er sieht nur das </ und das ist für ihn laut Standard das Ende vom Script-Bereich.
Lo!
Moin!
Hi!
Aber dann ist das doch ein ziemlich "dummer" Parser oder?
Ja, denn der "dumme Parser" parst HTML.
Und da kommen wir auch gleich zur zweiten Lösung, die aber nicht für XHTML angewendet werden sollte, weil künftige Browser dann womöglich das gesamte Script als Kommentar ansehen und zwar - anders als bisherige - auch das Javascript.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script type="text/javascript">
<!-- // wir beginnen hier einen HTML-Kommentar
[code lang=javascript]alert('</script>');
// Den wir hier wieder beenden -->
</script>
</head>
<body>
test
</body>
</html>
[/code]
Dritte (beste) Lösung:
Das Javascript als externe Datei ablegen oder generieren. Funktioniert mit allen Browsern.
Hi!
Ja, denn der "dumme Parser" parst HTML.
Und da kommen wir auch gleich zur zweiten Lösung, [...]
<script type="text/javascript">
<!-- // wir beginnen hier einen HTML-Kommentar
alert('</script>');
// Den wir hier wieder beenden -->
Und dann haben wir nur ein Problem mit dem Pre-/Postfix-Decrement-Operator -- oder wann immer zwei Minus-Zeichen im Javascript-Code auftreten, denn die beenden den HTML-Kommentar. Und das tolle daran ist, man kann sie nicht maskieren, weil sie a) Jacascript-Code sind und b) auch nicht mit irgendwelche HTML-NCRs, weil diese im Script-Bereich nicht aufgelöst werden dürfen.
Lo!
Moin!
Und dann haben wir nur ein Problem mit dem Pre-/Postfix-Decrement-Operator --
Ich habe nicht grundlos das externe Skript ausdrücklich als beste Lösung benannt.
MFFG (Mit freundlich- friedfertigem Grinsen)
fastix
Hi,
Und da kommen wir auch gleich zur zweiten Lösung, die aber nicht für XHTML angewendet werden sollte
Dafür gibt's ja CDATA.
http://de.selfhtml.org/html/xhtml/unterschiede.htm#script_style
MfG ChrisB
Moin!
Und weiter: Gibt es workarounds oder Maßnahmen, um user-inputs entsprechend zu filter, damit sie, falls sie nach Eingabe irgendwo in die Seite geschrieben werden nicht alles kaputt machen wenn ein "</script>" eingegeben wird !?
Das Problem besteht bei der Eingabe hier nicht. Überzeuge Dich:
<html>
<head>
[code lang=javascript] <script type="text/javascript">
function Alarm() {
alert("wont be alerted");
alert(document.getElementById('t1').value);
alert("will be written to document");
}
</script>
</head>
<body>
<form>
<input type="text" id="t1" /><input type="button" onclick="Alarm()" value="Klick!" />
</form>
</body>
</html>[/code]
Verabeitest Du jedoch Daten auf dem Server, dann ist die Verwendung von Funktionen, welche die Ausgabe von tags nachhaltig verhindern nicht nur angezeigt sondern regelrecht Pflicht.
in PHP wäre sowas wie
echo htmlentities($str);
angezeigt. Dann würde aus der Eingabe "</script>" sowas wie "<script>"
Soll die Ausgabe jedoch in einem alert erfolgen, dann gibt es mit entities nicht, Du musst so handeln wie Struppi es beschrieb. Also in PHP etwa:
echo 'alert("' . str_replace('</', '<\/') . '");';
MFFG (Mit freundlich- friedfertigem Grinsen)
fastix
Hi,
kann mir das bitte mal einer erklären?
das <script>-Element wird beim ersten Auftreten der Zeichenkette "</" geschlossen. HTML kann kein JavaScript.
Cheatah
Länger nicht gesehen, im Urlaub gewesen?
kann mir das bitte mal einer erklären?
das <script>-Element wird beim ersten Auftreten der Zeichenkette "</" geschlossen. HTML kann kein JavaScript.
Das scheint nicht zu stimmen:
<script type="text/javascript">
alert('das Ende </ende>');
</script>
Im gegensazu dazu:
<script type="text/javascript">
alert('das Ende </script>');
</script>
Struppi.
Hi!
das <script>-Element wird beim ersten Auftreten der Zeichenkette "</" geschlossen. HTML kann kein JavaScript.
Das scheint nicht zu stimmen:
Was die Browser daraus machen steht auf einem anderen Blatt. Spezifiziert ist es jedenfalls so.
Der Inhalt vom script-Element ist als CDATA festgelegt. Und dazu weiß HTML 4.01 eine Ausnahme:
Although the STYLE and SCRIPT elements use CDATA for their data model, for these elements, CDATA must be handled differently by user agents. Markup and entities must be treated as raw text and passed to the application as is. The first occurrence of the character sequence "</" (end-tag open delimiter) is treated as terminating the end of the element's content. In valid documents, this would be the end tag for the element.
Lo!
Was die Browser daraus machen steht auf einem anderen Blatt. Spezifiziert ist es jedenfalls so.
Das hatte ich mir schon fast gedacht. Es gibt (und gab) aber kein Browser, der diese Regel so umsetzt.
Struppi.
Hi!
Was die Browser daraus machen steht auf einem anderen Blatt. Spezifiziert ist es jedenfalls so.
Das hatte ich mir schon fast gedacht. Es gibt (und gab) aber kein Browser, der diese Regel so umsetzt.
Macht ja aber nichts. Solange man </ zu </ umschreibt, kann kommen was will - beliebige Zeichenfolge hintendran oder regelkonformer UserAgent (muss ja nicht imemr ein Browser sein).
Lo!
Was die Browser daraus machen steht auf einem anderen Blatt. Spezifiziert ist es jedenfalls so.
HTML 4 ist 12 Jahre alt und diese Parser-Regeln wurden nie in der Praxis umgesetzt. Näher an der Realität (weil dieser hinterherspezifiziert) ist da HTML5, welches den Parser genauer spezifiziert. Dort ist auch festgelegt, dass der Parser script-Inhalt bis </script> parst, nicht bis zu einem beliebigen </.
http://www.w3.org/TR/html5/tokenization.html#script-data-end-tag-name-state
<script> alert('<b>foo</b>'); </script> ist daher valides HTML5.
Wenn man mal nachdenkt, welcher Grund sollte auch bestehen, das script-Element bei </ zuzumachen. Klar, das ist nicht SGML- oder XML-konform, denn ein SGML-Parser nimmt </ natürlich immer als End-Tag-Anfang. Aber HTML 4 hat hier ohnehin eine Ausnahme von SGML festgelegt: »Although the STYLE and SCRIPT elements use CDATA for their data model, for these elements, CDATA must be handled differently by user agents.« Das ist natürlich nicht SGML-konform, d.h. ein normaler SGML-Parser, der nur die DTD kennt, ignoriert m.W. diese (nirgends maschinenlesbar notierte) Sonderregel und ersetzt bspw. Entity-Referenzen. Das habe ich nie verstanden, das war m.W. schon immer inkonsistent. HTML5 räumt da jetzt auf, wobei für XHTML5 natürlich die XML-Regeln gelten.
Mathias
Hi,
<html>
<head>
<script type="text/javascript">
alert("wont be alerted");
alert("</script>");
alert("will be written to document");
</script>
</head>
<body>
</body>
</html>
>
> ausgegeben wird:
>
> `"); alert("will be written to document"); `{:.language-html}
>
> Ich kann nicht verstehen, warum das schließende script-tag, obwohl es im String steht, alles kaputt macht.
Weil der HTML-Parser sich nicht dafür interessiert, ob sich die Zeichenfolge </script> in einem Javascript-String befindet. Er sucht nach dem öffnenden script-Tag einfach das erste schließende script-Tag (also die Zeichenfolge </script>
(genaugenommen müßte er sogar den Script-Block beim ersten </ beenden)
Der Javascript-Parser bekommt also nur
alert("wont be alerted");
alert("
vorgeworfen. Und das kann er nicht erfolgreich parsen, also wird das Script dann auch nicht ausgeführt, da es ja syntaktisch falsch ist.
> Nicht mal das erste alert wird ausgeführt.
Natürlich nicht.
> Hat jemand dafür eine Erklärung?
s.o.
Sorge dafür, daß die Zeichenfolge </ nicht im Javascript auftaucht, z.B. durch escapen des / per \, also <\/ oder durch Aufteilen des Strings "<" + "/script".
> Und weiter: Gibt es workarounds oder Maßnahmen, um user-inputs entsprechend zu filter, damit sie, falls sie nach Eingabe irgendwo in die Seite geschrieben werden nicht alles kaputt machen wenn ein "</script>" eingegeben wird !?
Ja, behandle sie kontextgerecht, zwei Möglichkeiten für Script hab ich schon gegeben, für HTML allgemein: < durch < ersetzen, wenn keine Tags gewünscht werden.
cu,
Andreas
--
[Warum nennt sich Andreas hier MudGuard?](http://MudGuard.de/)
[O o ostern ...](http://ostereier.andreas-waechter.de/)
Fachfragen per Mail sind frech, werden ignoriert. Das Forum existiert.