Frage PHP: HTML-Attribut-Kodierung / JavaScript-Dekodierung


Was ist der richtige Weg, um nicht vertrauenswürdige Daten für den HTML-Attributkontext zu kodieren? Beispielsweise:

<input type="hidden" value="<?php echo $data; ?>" />

Ich benutze normalerweise htmlentities() oder htmlspecialchars() um dies zu tun:

<input type="hidden" value="<?php echo htmlentities($data); ?>" />

Kürzlich stieß ich jedoch auf ein Problem, bei dem meine Anwendung beschädigt wurde, als die Daten, die ich übergeben musste, eine URL waren, die an JavaScript übergeben werden musste, um den Seitenspeicherort zu ändern:

<input id="foo" type="hidden" value="foo?bar=1&amp;baz=2" />
<script>
    // ...
    window.location = document.getElementById('foo').value;
    // ...
</script>

In diesem Fall, foo ist ein C-Programm und es versteht nicht die codierten Zeichen in der URL und in den segfaults.

Ich kann einfach den Wert in JavaScript greifen und so etwas tun value.replace('&amp;', '&'), aber das scheint klugig und funktioniert nur für kaufmännische Und-Zeichen.

Meine Frage ist also: Gibt es einen besseren Weg, um Daten zu kodieren oder zu dekodieren, die in HTML-Attribute eingefügt werden?

Ich habe alles gelesen OWASPs XSS-Vorbeugungs-Cheatsheetund es klingt für mich so lange, wie ich vorsichtig bin, meine Attribute zu zitieren, dann ist das einzige Zeichen, das ich kodieren muss, das Zitat selbst (") - in diesem Fall könnte ich etwas wie verwenden str_replace('"', '&quot;', ...) - Aber ich bin mir nicht sicher, ob ich es richtig verstehe.


7
2018-05-01 20:36


Ursprung


Antworten:


Ihre aktuelle Methode der Verwendung htmlentities() oder htmlspecialchars() ist der richtige Ansatz.

Das von Ihnen angegebene Beispiel ist korrektes HTML:

<input id="foo" type="hidden" value="foo?bar=1&amp;baz=2" />

Das kaufmännische Und im value-Attribut muss in der Tat HTML-codiert sein, andernfalls ist Ihr HTML-Code ungültig. Die meisten Browser würden es mit einem korrekt analysieren & da drin, aber das ändert nichts an der Tatsache, dass es ungültig ist und Sie es richtig sind, es zu kodieren.

Ihr Problem liegt nicht in der Codierung des Wertes, was gut ist, sondern darin, dass Sie Javascript-Code verwenden, der es nicht richtig dekodiert.

In der Tat bin ich überrascht, da Ihr JS-Code auf das DOM zugreift und das DOM die dekodierten Werte zurückgeben soll.

Ich habe eine JSfiddle geschrieben, um das zu beweisen: http://jsfiddle.net/qRd4Z/

Wenn ich dies ausführe, gibt es mir eine Alarmbox mit dem entschlüsselten Wert, wie ich es erwartet habe. Ändern zu console.log gib auch das Ergebnis, das ich erwarte. Ich bin mir also nicht sicher, warum Sie unterschiedliche Ergebnisse erzielen. Vielleicht verwenden Sie einen anderen Browser? Es könnte sich lohnen, anzugeben, mit welchem ​​Sie testen. Oder haben Sie die Entitäten versehentlich doppelt codiert? Kannst du bestätigen, dass das nicht der Fall ist?


11
2017-07-10 21:31



Was ist der richtige Weg, um nicht vertrauenswürdige Daten für den HTML-Attributkontext zu kodieren?

Wenn Sie den Attributwert in doppelte Anführungszeichen setzen, ist htmlspecialchars () ausreichend.

 <input id="foo" type="hidden" value="foo?bar=1&amp;baz=2" />

Dies ist korrekt und der Browser wird senden foo?bar=1&baz=2 (entschlüsselt &amp;) zum Server. Wenn der Server nicht sieht foo?bar=1&baz=2, Sie müssen den Wert zweimal codiert haben.

Der Wert in Javascript sollte zurückgegeben werden foo?bar=1&baz=2 auch (z.B. document.getElementById('foo').value muss zurückkehren foo?bar=1&baz=2).

Zeigen Sie die Quelle der Seite mit Ihrem Browser an und sehen Sie sich die Quelle des Eingabefeldes an.

Wenn Sie den Wert des Eingabefelds mithilfe von Javascript ändern, muss das Skript die Codierung doppelt ausführen.

Übrigens sollte Ihr Programm wegen falscher Benutzereingaben nicht segfault werden;)


5
2017-07-10 21:26



Sie können das DOM verwenden, um den Wert zu dekodieren:

function decodeHTMLSpecialChars(input){
  var div = document.createElement('div');
  div.innerHTML = input;
  return div.childNodes.length === 0 ? "" : div.childNodes[0].nodeValue;
}

Dies wird die folgende Zeichenfolge rendern:

'http://someurl.com/foo?bar=1&amp;baz=2'

zu diesem:

decodeHTMLSpecialChars('http://someurl.com/foo?bar=1&amp;baz=2');
// => 'http://someurl.com/foo?bar=1&baz=2

Und nein, für HTML-Codierung und Decodierung, die htmlspecialchars und HTML-Escaping ist die Standardmethode und macht die Arbeit gut für Sie.


0
2017-07-10 21:25



Könntest du nicht einfach die html_entity_decode Funktion in PHPJS:

http://phpjs.org/functions/html_entity_decode

Ansonsten könnten Sie Base64 stattdessen Ihre Daten verschlüsseln ...


0
2017-07-11 02:42



Bitte beachten Sie, dass mit htmlentities wie es ist, hilft nicht!

Standardmäßig wird nur codiert " < > & 

Es entgeht nicht ' Das kann ein Problem verursachen!

Stellen Sie sicher, dass Sie Flags für die Funktionen verwenden, Sie finden die Verwendung und Beispiele Hier


0
2018-03-24 00:27