Hallo,
man kann eine auszugebende HTML Menge ja recht gut mit striptags() säubern. Aber manchmal geht das eben nicht gut, weil man einige Tags durchaus gut findet. Natürlich kann man die guten Tags stehen lassen, aber was passiert, wenn ein <img>-Tag nebenbei das macht:
Dann kann das Bild nicht geladen werden und das onerror-Attribut wird getriggert. Schon läuft JavaScript...
Das selbe gilt theoretisch für alle Attribute in allen Tags. Daher hab ich eine Filter-Routine gemacht, welche hier mehr Sicherheit schafft.
ACHTUNG: Das bietet keine alleinige Sicherheit! Man muss Tags wie zB <script> noch selbst entfernen (Tipp: striptags() Funktion von PHP). Es macht dann Sinn, wenn man bestimmte Tags (zB <form>, <input >, <img > etc.) behalten möchte. In dem Fall kann man mit dieser Funktion die verbliebenen Tags ganz einfach unschädlich machen.
Will das nicht vorenthalten, also bitte:
Und hier noch der Code für den verwendeten Zufallsgenerator:
Die folgenden Attribute werden innerhalb von beliebigen Tags entschärft, indem sie durch Zufallsbezeichner ersetzt werden:
onabort (bei Abbruch)
onblur (beim Verlassen)
onchange (bei erfolgter Änderung)
onclick (beim Anklicken)
ondblclick (bei doppeltem Anklicken)
onerror (im Fehlerfall)
onfocus (beim Aktivieren)
onkeydown (bei gedrückter Taste)
onkeypress (bei gedrückt gehaltener Taste)
onkeyup (bei losgelassener Taste)
onload (beim Laden einer Datei)
onmousedown (bei gedrückter Maustaste)
onmousemove (bei weiterbewegter Maus)
onmouseout (beim Verlassen des Elements mit der Maus)
onmouseover (beim Überfahren des Elements mit der Maus)
onmouseup (bei losgelassener Maustaste)
onreset (beim Zurücksetzen des Formulars)
onselect (beim Selektieren von Text)
onsubmit (beim Absenden des Formulars)
onunload (beim Verlassen der Datei)
javascript: (bei Verweisen)
script:
eval
Achtung, das arbeitet auch innerhalb von HTML Kommentaren etc. Das sollte bei der Ausgabe aber ja nicht stören...
Wenn es jemand erweitern oder verbessern möchte, dann gerne Bitte hier untendran posten.
Donald
man kann eine auszugebende HTML Menge ja recht gut mit striptags() säubern. Aber manchmal geht das eben nicht gut, weil man einige Tags durchaus gut findet. Natürlich kann man die guten Tags stehen lassen, aber was passiert, wenn ein <img>-Tag nebenbei das macht:
Code:
<img src="notknown.jpg" onerror="alert(1);">
Das selbe gilt theoretisch für alle Attribute in allen Tags. Daher hab ich eine Filter-Routine gemacht, welche hier mehr Sicherheit schafft.
ACHTUNG: Das bietet keine alleinige Sicherheit! Man muss Tags wie zB <script> noch selbst entfernen (Tipp: striptags() Funktion von PHP). Es macht dann Sinn, wenn man bestimmte Tags (zB <form>, <input >, <img > etc.) behalten möchte. In dem Fall kann man mit dieser Funktion die verbliebenen Tags ganz einfach unschädlich machen.
Will das nicht vorenthalten, also bitte:
PHP-Code:
/**
* Replaces all dangerous attributes from the html-tags in this document.
* Example:
* <img src="a.jpg" onerror="alert(1)" onload="alert(1)"> will get
* <img src="a.jpg" s5T38IwgH="alert(1)" s5T38IwgH="alert(1)">
*
* @param string $input document to clean
* @return string clean document
*/
function secureHTMLAttributes($input) {
// this attributes will get neutralized
$Attributes = Array("onabort", "onblur","onchange","onclick", "ondblclick","onerror","onfocus", "onkeydown",
"onkeypress","onkeyup","onload","onmousedown","onmousemove","onmouseout","onmouseover",
"onmouseup","onreset","onselect","onsubmit","onunload","javascript:","javascript :",
"eval", "script:", "script :");
$output = "";
for ($i=0;$i<=strlen($input);$i++){
$char = substr($input, $i, 1);
if ($char == ">") { $inside = $inside - 1; }
if ($inside < 1) {
if ($found != "") {
// check the content of the tag
$found = str_ireplace($Attributes, "s".GenerateCode(6), $found);
}
$output .= $found . $char;
$found = "";
} else {
$found .= $char;
}
if ($char == "<") { $inside = $inside + 1; }
}
return $output;
}
PHP-Code:
function GenerateCode($Length) {
$Code = "";
for ($x = 1; $x <= $Length; $x++) {
if (rand(1,100) < 51 ){
// number
$Code = $Code . rand(0,9);
} else {
// char
if (rand(1,100) < 50) {
// lowercase
$Zeichen = strtolower(chr(rand(65,90)));
$Code = $Code . $Zeichen;
} else {
// uppercase
$Zeichen = chr(rand(65,90));
$Code = $Code . $Zeichen;
}
}
}
return $Code;
}
Die folgenden Attribute werden innerhalb von beliebigen Tags entschärft, indem sie durch Zufallsbezeichner ersetzt werden:
onabort (bei Abbruch)
onblur (beim Verlassen)
onchange (bei erfolgter Änderung)
onclick (beim Anklicken)
ondblclick (bei doppeltem Anklicken)
onerror (im Fehlerfall)
onfocus (beim Aktivieren)
onkeydown (bei gedrückter Taste)
onkeypress (bei gedrückt gehaltener Taste)
onkeyup (bei losgelassener Taste)
onload (beim Laden einer Datei)
onmousedown (bei gedrückter Maustaste)
onmousemove (bei weiterbewegter Maus)
onmouseout (beim Verlassen des Elements mit der Maus)
onmouseover (beim Überfahren des Elements mit der Maus)
onmouseup (bei losgelassener Maustaste)
onreset (beim Zurücksetzen des Formulars)
onselect (beim Selektieren von Text)
onsubmit (beim Absenden des Formulars)
onunload (beim Verlassen der Datei)
javascript: (bei Verweisen)
script:
eval
Achtung, das arbeitet auch innerhalb von HTML Kommentaren etc. Das sollte bei der Ausgabe aber ja nicht stören...
Wenn es jemand erweitern oder verbessern möchte, dann gerne Bitte hier untendran posten.
Donald
Kommentar