Apostroph Kodierung und XSS in moderen Browsern

Während der Teilnahme an einem Bug Bounty Programm entdeckte Sebastian eine “script-context” XSS mit dem Injektionspunkt als String. Nahezu alle modernen Browser (z.B. FireFox, Chromium & der Internetexplorer) kodieren das Apostroph. Trotzdem ist eine Ausnutzung dieser Lücken unter Umständen möglich.

Die XSS

Das verwundbare Javascript sah ungefähr so aus:

1
2
3
<script>
var foo = 'bar [INJECTION]';
</script>

Der Wert eines Parameters, in diesem Beispiel ?foo= war eingebettet in einen JavaScript String, welcher nicht dekodiert wurde. Das bedeutet, dass man diese Lücke ausschließlich nutzen könnte, wenn man einen String wie ';+alert(1)+' injezieren könnte, weil alle anderen Versuche fehlschlagen würden. (Wenn dir ein cooler Bypass dafür einfällt, lass es uns gern wissen :)). Wenn du ein bisschen rumprobieren möchtest, nutze dazu unsere Challenge. Sebastian hat einen kleinen Webserver in Python geschrieben, welcher die Situation nachstellt.

Das Problem

Viele moderene Browser (z.B. FireFox, Chromium, InternetExplorer, aber bspw. nicht der Safari-Browser) kodieren ein Apostroph automatisch auf Grund von Sicherheitsbedenken. Für einen Bughunter könnte das dann so aussehen, als ob eine Applikation sicher wäre, weil ja augenscheinlich kein Ausnutzen möglich ist, das ist aber weit gefehlt - denn manche Browser lassen es trotzdem zu den eingefügten Code auszuführen. Um zu schauen, ob dein Browser auch Apostrophe kodiert kannst du einfach folgende 2 Schritte in der Konsole durchführen:

  • Führe zunächst nc -l -p 1337 aus
  • Verbinde dich zu http://localhost:133/?foo=bar'
1
2
3
4
5
6
7
8
> nc -l -p 1337
GET /?foo=bar%27 HTTP/1.1
Host: localhost:1337
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4

Wie man sehen kann, wechselt das Apostroph von ' zu %27. ( int(0x27) = 39 = Die Position des Apostrophs in der ASCII Tabelle)

Der RFC 1738 besagt, dass die Kodierung des Zeichens optional ist, da es sich nicht um ein reserviertes URL-Zeichen handelt.

Thus, only alphanumerics, the special characters “$-_.+!*’(),”, and
reserved characters used for their reserved purposes may be used
unencoded within a URL.

Wirft man einen Blick in den Bugreport bei Mozilla , so argumentiert ein Entwickler, dass das Feature “apostroph”-basierte XSS Lücken verbeugend verhindere.

Wenn man demnächst einer XSS begegnet bei der die Webapplikation das Apostrophe nicht automatisch dekodiert, so ist nun klar, dass es Browser gibt, in der die Lücke durchaus ausnutzbar ist. Grundsätzlich ist der Schutz durch Browser wünschenswert, aber es findet gewissermaßen eine Verschiebung der Verantwortlichkeiten statt, denn die eigentliche Lücke wird im Code verursacht und nicht durch den Browser, der in dem Fall nur den Code interpretiert.

Die Liste

Wir denken, dass es eine intressante Sache wäre eine Liste darüber zu haben, welche Browser die Apostrophe automatisch (de)kodieren und haben deshalb Folgendes angefertigt:

Wenn du noch weitere Browser nutzt oder kennst sende uns bitte einen Tweet @internetwache und wir werden die Liste regelmäßig aktualisieren. :)

Encoding

  • Chrome/ium
  • IE (>=11)
  • Firefox
  • Opera

Kein encoding

  • Arora
  • Dillo
  • Curl
  • Konqueror
  • Luakit
  • Midori
  • Safari

Viel Spaß mit der Liste ;)

Das Team der Internetwache.org