Als JavaScript als Sprache designed wurde stand einfache Objektorientierung, Flexibilität und Mächtigkeit im Vordergrund - der Scope war allerdings, mit der Bearbeitung von HTML-Formularen im Browser, eher beschränkt. Heute gibt es Codebasen mit mehreren Millionen Zeilen Code in JavaScript, und praktisch jedes Problem einer Enterprise-Applikation kann mit JavaScript gelöst werden. Der Talk zeigt welche Wirkung Sprachdesign und Engine von JavaScript auf die Anwendungsfelder von heute hat, welche eigenen Fehlerklassen dadurch entstehen und wie man sie in der praktischen Arbeit umgeht.
1. JavaScript Security
aus dem Blickwinkel
des Java-Entwicklers
1Donnerstag, 15. Mai 14
Willkommen zusammen!
Ich bin Johann, und ich hasse sowohl Firmenmarketing wie auch Ego-Surfing-Slides, daher
lasse ich die Vorstellung weg und steige direkt in den Vortrag ein, ist das ok? Danke :-)
Ah, ein Thema aber trotzdem - wer war in dem Agile Management-Vortrag von Sandra und
Ilja? Da würde ich mich gerne drüber unterhalten. Was die da machen ist cool, das ist wie
Security, nur dass die Mädels und Jungs Management hacken statt Rechnern. Ehrenwert.
2. Warum ausgerechnet
JavaScript Security?
Auf einer Java Konferenz?
2Donnerstag, 15. Mai 14
Es freut mich, dass so viele Leute hier sind heute - denn eigentlich macht das auf den ersten
Blick ja gar keinen Sinn - schliesslich sind wir auf eine Java-Konferenz, und nicht auf einer
JavaScript-Konferenz. Und warum gibt es dann einen Talk zu Javascript Security?
3. Java ist
(nicht wirklich und eher indirekt)
schuld.
3Donnerstag, 15. Mai 14
Der erste Grund ist einfach - weil Java bei den Problemen heute unabsichtlich und ohne
Schuld eine massgebliche Rolle gespielt hat.
4. 4Donnerstag, 15. Mai 14
Auch der zweite Grund ist offensichtlich.Ich weiss, man darf keiner Statistik trauen, aber die
Leute von Redmonk machen im Gegensatz zu Tiobe die Statistik auf Basis von echten
Diskussionen und echte Commits - konkret Stackoverflow und Github machen. Die Statistik
ist vom Januar. In welcher Ecke vermutet Ihr Javacript?
5. 5Donnerstag, 15. Mai 14
Genau, offensichtliche Frae - ganz rechts oben, weniger Fragen als Java auf Stackoverflow,
dafür mehr Lösungen auf Github. Statistisch machen Programmierer also etwas da oben in
der Ecke. In Realität ist Java vermutlich sogar noch etwas dominanter, weil viel firmeninterne
Entwicklung weder Spuren auf Stack-Overflow noch auf Github hinterlässt.
6. Wessen Anwendungen
basieren auch auf JavaScript?
6Donnerstag, 15. Mai 14
Wer macht hier Anwendungen, die zum Teil auch auf JavaScript basieren?
7. 7Donnerstag, 15. Mai 14
Die Verbindung zwischen Java und JavaScript ist aber schon erheblich älter. Wer erinnert sich
noch an die Zeit, als die Logos so aussahen?
8. LiveScript
8Donnerstag, 15. Mai 14
Die ganze Geschichte geht auf 1995 zurück. Da hat der Herr auf der linken - Brendan Eich -
genau, der der gerade als President der Mozilla Foundation zurücktreten musste weil er
Jehova gesagt hat - die Frage von der Netscape Communications bekommen, ob er nicht eine
Programmiersprache entwickeln wollte.
9. LiveScript
•Scheme-basiert
•Easy-to-use
•Eingebettet
9Donnerstag, 15. Mai 14
Brendan wurde zu Netscape geholt mit der Erwartung, dort ein In-Browser-Scheme zu
entwickeln. Es sollte einfach zu entwickeln sein und auf jeden Fall für Amateure geeignet
sein. Und es sollte in HTML selbst eingebettet sein. Intern war es übrigens mit dem Namen
Mocha unterwegs.
Quelle: https://brendaneich.com/tag/history/
10. 2 Sprachen in einem Browser?!
10Donnerstag, 15. Mai 14
Zur gleichen Zeit 1995 hatte die Netscape Communications aber auch begonnen mit Sun zu
verhandeln, um Java - initial damals noch mit dem Namen Oak unterwegs - einzubetten.
Daraufhin stritt man erst mal, ob man tatsächlich zwei Sprachen braucht, oder ob nicht eine
reichte. Und was macht man, wenn man einen Interessenkonflikt hat?
11. Wenn schon 2 Sprachen, dann
ähnlicher Syntax.
JavaScript für Amateure
und einfache Aufgaben
Java(Kompenten) für
richtige Applikationen.
11Donnerstag, 15. Mai 14
Genau, einen faulen Kompromiss: zwei Sprachen, aber der Syntax nicht zuweit auseinander.
Die eine Sprache eingebettet, einfach und als Glue-Sprache zu der richtigen
Programmiersprache. Und eine richtige Programmiersprache für die Applikationsentwicklung.
12. 10 Tage!
Java-ähnlicher Syntax
Keine klassenbasierte Objektorientierung
Prototypenbasierte Objektorientierung
Primitive & Object: string & String
First-Class-Functions
12Donnerstag, 15. Mai 14
Nach dieser Einigung hatte er 10 Tage Zeit, das ganze dann tatsächlich zu implementieren. Es
sollte Javaähnlicher Syntax sein, aber für nicht so mächtige Aufgaben. Die Trennung von
primitiven und Objekttypen - etwa String vs. string wurde von Java übernommen, ebenso die
Jahr-2000-Bugs, wie Brendan anmerkt.
Die Objektorientierung nutzt das Self-und LISP-entlehnte Konzept der Prototypenbasierten
Vererbung, und es gibt First-Class-Funktionen, sprich: die selbst als Parameter genutzt
werden kann. Deshalb gibt es auch anonyme Funktionen in JavaScript.
Quelle: http://www.computer.org/csdl/mags/co/2012/02/mco2012020007.html
13. •Transparente GIFs
•HTML-Frames
•OLE
•JavaScript
•Java
13Donnerstag, 15. Mai 14
Und so war man Anfang 2006 tatsächlich in der Lage, JavaScript zum ersten Mal der Welt zu
präsentieren - Der Name wurde geändert, und gemeinsam mit so tollen Features wie
transparenten GIFs, Frames und dem Support für Microsofts Object Linking and Embedding
wurde der Netscape Navigator 2 released.
Java für die richtige Entwicklung, Javascript für Formularvalidierung und Glue-Code.
14. 8 Jahre später:
World Domination...14Donnerstag, 15. Mai 14
Und heute, 8 Jahre später, hat JavaScript quasi World Domination erreicht. Wer erinnert sich
noch an die Zeiten, als man allen Freunden und Verwandten empfohlen hat, JavaScript im
Browser zu deaktivieren? Heute geht praktisch die Hälfte des Internets dann nicht mehr.
15. Smartphones
Browsers
Tablets TVs
OS Embedded Devices
Webapplikationen
8 Jahre später:
World Domination...
Server
15Donnerstag, 15. Mai 14
Und nicht nur da ist es passiert - das, was die Sun mit Oak erreichen wollte ist heute
praktisch mit JavaScript der Fall geworden. Für jedes Device das neu entsteht gibt es auch
gleich einen Standard, wie es von JavaScript unterstützt wird. Inzwischen laufen grosse Sites
auf node.js.
Mein Fernseher möchte für den SmartTV-Anteil bitteschön JavaScript-basiertes HBBTv
16. Enterprise JavaScript
npmjs.org: 75.000 module
github: 250.000 repositories
16Donnerstag, 15. Mai 14
Und nicht nur die Verbreitung hat sich geändet - die Applikationen sind auch deutlich größer
geworden. Wir haben inwischen Codebasen die sehr groß sind. npmjs.org hat fast 75.000
Module, Github hat mehr als 250.000 JavaScript Repositories (Java zum Vergleich nur
150.000).
17. JavaScript macht heute
viele der Dinge,
für die eigentlich
Java gebaut wurde.
17Donnerstag, 15. Mai 14
Faktisch macht JavaScript heute viele Sachen, für die eigentlich eine Sprache wie Java gebaut
wurde. Das klingt erst mal nicht schlimm, frei nach der Devise: es ist doch toll, wenn
JavaScript das auch kann.
18. JavaScript fehlen viele
Eigenschaften, die für seine
Aufgaben heute
benötigt werden.
Java hätte sie gehabt.
18Donnerstag, 15. Mai 14
Der Punkt ist nur: es kann es gar nicht. Es fehlen nämlich einige Eigenschaften, die Java bietet
und die Javascript nicht hat, schlicht weil niemand erwartete dass es dort eingesetzt wird wo
es heute passiert. Java hätte sie gehabt, trotzdem wurde JavaScript eingesetzt.
21. 21Donnerstag, 15. Mai 14
Den Klassiker kennt vermutlich jeder - Float gibt je nach Anzahl Nachkommastellen
interessante Ergebnisse. Aber: bei JavaScript gibt es nur einen Numbers-Typ, und der ist
Float. Es gibt weder Integer noch Decimal noch double, es gibt nur Numbers, der einem 64-
Bit-Float entspricht.
22. Semicolon-
Insertion
;
22Donnerstag, 15. Mai 14
Hier gibt es zwei mal die gleiche Funktion, trotzdem gibt sie unterschiedliche Ergebnisse.
Sieht jemand, woran es liegt? JavaScript richtet sich an Amateure. Also ist der Interpreter
tolerant. Und so wird netterweise für den Programmierer ein Semikolon dort eingefügt, wo er
es vergessen haben könnte.
23. „Überraschendes“
Verhalten
Unter einer Äquivalenzrelation
versteht man in der Mathematik
eine Relation, die reflexiv,
symmetrisch und transitiv ist.
23Donnerstag, 15. Mai 14
Daneben verhält sich JavaScript oft überraschend und anders als man es als Programmierer
normaler Sprachen gewohnt wäre. Es gibt zwar eine Type null, aber der wird von typeof nicht
geliefert - damit kann man mit typeof tatsächlich nicht auf objekte prüfen, weil null eben
auch “objekt“ zurückliefert. Not a Number selbst ist als Typ Number, natürlich.
24. Inkonsistentes
Verhalten
Unter einer Äquivalenzrelation
versteht man in der Mathematik
eine Relation, die reflexiv,
symmetrisch und transitiv ist.
24Donnerstag, 15. Mai 14
Aber nicht nur einzelnes Verhalten ist überraschend, das bricht auch mit einigen
Grundannahmen, die wir haben - zum Beispiel bei der Äquivalenzrelation == - keine
Transitivität.
25. First Class Functions:
auch Builtin-Functions sind
überschreibbar.
25Donnerstag, 15. Mai 14
Und weil JavaScript first Class funktionen hat, sind diese wie Variablen oder Attribute
manipulierbar. Das gilt auch für die, die die Plattform mitliefert.
26. Das gilt auch für node.js-Module
var http = require('http');
oldfunc = http.createServer;
http.createServer = function (myfunc) {
console.log('Hijacking createServer');
newfunc = function (req, res) {
result = myfunc(req, res);
console.log('MITM Request:');
console.log(req);
console.log('MITM Response:');
console.log(res);
return result;
}
return oldfunc(newfunc);
}
26Donnerstag, 15. Mai 14
Und das gilt auch für Frameworks und Libraries - auch dort kann ich einfach die Infrastruktur
zur Laufzeit manipulieren. Hier ein Beispiel für den Kern von Node.js, den Serverloop. Dort
überschreibe ich in diesem Beispiel die createServer-Funktion durch eine neue, die zwar das
gleiche tut - aber zusätzlich alle Empfangenen und alle gesendeten Daten mitloggt. Der
Missbrauch wäre einfach - indem die Daten an eine dritte Partei gegeben würden.
27. Object.defineProperty(global,
key, {writable: false,
configurable: false});
Ecma-Script 5
27Donnerstag, 15. Mai 14
Seit Ecmascript 5 ist es möglich, das Überschreiben zu verhindern - meist wird das aber nicht
gemacht - weil es zwar zur Laufzeit unerwünscht ist, aber für die prototypenbasierte
Objektorientierung erforderlich ist.
28. Wenn JS-Code injected
werden konnte
ist meist kein anderer Code
mehr vertrauenswürdig.
28Donnerstag, 15. Mai 14
Damit sind wir bei einem Kernunterschied zwischen JavaScript und Java, bzw. Javascript und
kompilierten VM-Sprachen: eine Kompromittierung ist immer vollständig. Ich kann auch
keiner (Security-)Library, keiner Authentifzierung, keiner Logging-Library mehr trauen.
30. von Neumann-Architektur
CPU
BUS
Speicher
30Donnerstag, 15. Mai 14
Genau, dass ist János Neumann, heute eher als John von Neumann bekannt. Und der ist
Namensgeber der von-Neumann-Architektur, die ähnlich der Beschreibung oben aussieht -
bei ihm ist natürlich noch I/O mit dabei, und oben wird in Rechen- und Steuerwerk
unterschieden.
31. Speicherschutz fehlt
CPU
BUS
Speicher:
Echte Daten
Laufzeitdaten: Heap, Stack
Code
31Donnerstag, 15. Mai 14
Die von Neumann-Architektur hat einen Hasenfuss, wenn man sie direkt benutzt: der
Speicherschutz fehlt ihr. Weil der gleiche Speicher für Daten benutzt wird, kann eine
Datenmanipulation zu einer Code-Execution führen.
32. •Buffer Overflows
•Integer Overflows
•Format String Bugs
•Use after Free
•Stack Smashing + ROP
Speicher:
Echte Daten
Laufzeitdaten: Heap, Stack
Code
32Donnerstag, 15. Mai 14
Und genau diese Vermischung hat zu den wichtigsten Exploit-Vektoren der vergangenen
Jahrzehnte geführt. Weil Sprachen wie C und C++ keinen eigenen Speicherschutz mitbringen,
passieren solche Lücken im Rahmen der normalen Programmierung.
33. Java
bietet
Speicherschutz.
33Donnerstag, 15. Mai 14
Moderne Sprachen wie Java, Python oder C# bieten durch die Sprache selbst Speicherschutz,
und dementsprechend findet diese Art von Attacken praktisch nicht statt. Wenn es dann doch
mal knallt, liegt es im Regelfall an Fehlern in der Laufzeitumgebung selbst oder an der
Nutzung von fremden Code, etwa über JNI.
34. Browser: Daten, Code, Darstellung
OS: Laufzeitdaten, Heap & Stack
Für den Browser sind
Daten, Code und
Darstellung das gleiche
34Donnerstag, 15. Mai 14
Aber warum erwähne ich das? Weil beim Design von JavaScript etwas ganz ähnliches passiert
ist: Daten, Code und Darstellung sind das gleiche, und zwar in der Übertragung. Alles findet
oder kann in HTTP / HTML stattfinden. Und so finden wir an fast jeder Ecke von JavaScript
Wiedergänger der alten Exploits, die wir schon aus den seeligen C-Zeiten kennen.
35. „Eigentlich wollte ich
doch nur Daten bzw. Layout
schreiben.“
XSS
35Donnerstag, 15. Mai 14
XSS, dass der Kollege vorhin schon vorgestellt hat, ist im wesentlichen dieser Tatsache
geschuldet. Eigentlich sollte nur mit Daten oder Layout umgegangen werden, und niemand
hatte die Absicht, Code zu executen. Trotzdem ist es irgendwie passiert.
36. KXSS
<p>Name: Hartmann</p>
<p>Name: Hartmann<script>alert(1);</
script></p>
Nach der Hochzeit mit Frau „<script>alert(1);</script>“:
36Donnerstag, 15. Mai 14
Und genau das ist mit den Daten so eine Sache. Wenn man einen normalen Namen trägt ist
das kein Problem - wenn man allerdings eine Frau bzw. Herrn <script>alert(1);</script>
heiratet und den Doppelnamen anfängt, verhält sich die Website zukünftig komisch.
39. KXSS
<a href=“javascript:alert(/Hi!/);“>Click me</a>
39Donnerstag, 15. Mai 14
Und wenn man schon JavaScript direkt auf der Seite nutzen kann, warum bieten wir es dann
nicht auch gleich in der URL-Notation an? Das muss man sich mal auf der Zunge zergehen
lassen - ein Protokoll, dass eigentlich nur auf Ressourcen zeigen soll, wird so zu einer
Execution Engine gemacht. Aber im hier dargestellten Kontext - als Link - macht das
durchaus noch Sinn.
41. KXSS
<table background=“javascript:...
41Donnerstag, 15. Mai 14
Und nicht nur da - es gab eine Weile die Möglichkeit, den Hintergrund einer Tabelle über
JavaScript zu setzen. Glücklicherweise behandeln die HTML-Parser jetzt die URLs
kontextabhängig und executen nur noch dort, wo tatsächlich eine Execution erwartet und
erwünscht ist.
42. KXSS
<input value=“12“ onmouseover=“alert(1);“>
42Donnerstag, 15. Mai 14
Dann haben die Jungs von Netscape noch mal weitergedacht, und kamen auf die Idee, das
ganze doch noch mal Inline machen zu können, wie damals in Delphi, einfach eine Aktion an
das GUI-Element koppeln. Oder wie bei Visual Basic.
43. KXSS
<style>a: expression(alert(1))</style>
43Donnerstag, 15. Mai 14
Und wäre es nicht aus super, wenn man die Darstellung, die inzwischen über CSS gesteuert
wird, automatisieren könnte? Glücklicherweise mit IE8 endgültig deaktiviert, und IE-only.
46. KXSS
46Donnerstag, 15. Mai 14
Und wenn wir schon mal dabei sind ... wir könnten doch auch Plugins damit steuern. Das
wäre doch super. Und damit hätten wir auch endlich wieder Zugriff auf die ganzen Super Bugs
aus der C-Welt: Buffer Overflows, Format String Bugs, Integer Overflows.
47. KXSS
47Donnerstag, 15. Mai 14
Und generell, wäre es nicht super, wenn jeder, der in Zukunft neue Dinge im Browser macht,
sie auch gleich scripten könnte? Dann könnten wir alles Super automatisieren!
MathML und JavaScript war so kaputt, das Chrome es nach wenigen Versionen wieder
rausgeworfen hat.
48. Es gibt viele Orte, an denen eine
Code-Execution möglich ist.
<p>Name:
Hartmann>script<alert(1);>/
script<</p>
<input type=text value=“Hartmann"
AUTOFOCUS onfocus="alert(1);“>
<script>
plz = 80331;alert(1);
<script>
48Donnerstag, 15. Mai 14
Es gibt also beliebig viele Orte, an denen einen Javascript Execution möglich ist. Und jeder
Ort benötigt ein anderes Escaping. Oben wird direkt in HTML injected - da muss ich vor allem
das Öffnen von Tags verhindern. Im Attribut muss ich einen Escape aus dem Wert verhindern.
Und wenn ich einen Wert direkt in JavaScript ausgebe hilft mir gar kein Filter, weil ich schon
im ausführbaren Scope bin. Da hilft nur Whitelisting.
49. Es gibt viele Orte, an denen eine
Code-Execution möglich ist.
HTML: htmlEscape
JavaScript Strings: javascriptEscape
JavaScript Values: whitelist
Attribute/Event Names: whitelist
Attribute Values: javascriptEscape
Urls: htmlEscape
WYSIWYG: AntiSamy,JSOUP49Donnerstag, 15. Mai 14
Hier habe ich mal gesammelt, was die Methoden der Wahl sind beim Einsatz von Spring MVC.
Es gibt auch XSS-Blacklisting-Filter oder Web Application Firewalls. Wer setzt hier einen
Blacklisting-Filter ein? Wir kommen noch dazu, warum die nicht helfen können.
50. Und es gibt Orte, die
man selbst baut. 50Donnerstag, 15. Mai 14
Klar gibt es noch mehr!
51. KXSS
<div data-dojo-type="dojox/calendar/Calendar"
data-dojo-props="startDate: new Date(2012, 0, 1), endDate:
new Date(2012, 0, 9)"
style="position:relative;width:500px;height:500px"></div>
51Donnerstag, 15. Mai 14
Wir haben ja schliesslich noch JavaScript Libraries. Und auf einmal gibt es Properties die
Aktionen auslösen, die ich noch gar nicht kenne - zum Beispiel über Widgets. In HTML5 gibt
es das auch, aber da triggern sie kein JavaScript, das eigene Lücken enthalten kann.
52. KXSS
Vorher galt:
Attribut mit on* = Event -> Triggert JavaScript
data-dojo-attach-event
52Donnerstag, 15. Mai 14
Und das ist wichtig - denn vorher konnte man sich darauf verlassen, dass JavaScript nur über
Events, also über Attribute, die mit on* beginnen getriggert wurde - und alles andere
funktioniert automatisch.
53. KXSS
53Donnerstag, 15. Mai 14
Da steht ja nicht umsonst „write less, do more“ drunter. Das passiert tatsächlich.
54. KXSS$()
54Donnerstag, 15. Mai 14
Das wird zum Beispiel mit der sehr mächtigen $() funktion gemacht, die abhängig von Inhalt
unterschiedliche Dinge tut. Das erlaubt einem sehr schnell zu sein. Das ist cool.
Aber das bedeutet auch, dass man nicht immer weiss, was passiert. Und das ist ein Problem.
55. KXSS
Sink: eine Funktion,
die ein Risiko darstellt, wenn ihr
nicht vertrauenswürdiger Input
übergeben wird.
55Donnerstag, 15. Mai 14
In Security spricht man von einer Sink wenn man eine Funktion hat, die in einem Security-
Problem resultiert, wenn sie fremde Daten bekommt oder die Daten nicht sanitized sind.
SQL-Funktionen sind solche Sinks, wenn ich dort einen String direkt eingebe, dann wird er
ungefiltert der Datenbank übergeben und kann SQL-Injections erzeugen. eine
Multiplikationsfunktion wäre dementsprechend Risikofrei.
56. KXSS
$() ist eine Sink
$("<img src='dd' onerror='alert(1)'>");
56Donnerstag, 15. Mai 14
Und genau da kommt unser Problem her - $() ist eine Sink, und nicht jeder weiss es.
Ich darf also $() nur validierten Input in die Hand geben.
Quelle: https://www.owasp.org/images/9/95/JS_Libraries_Insecurity_-_Stefano_DiPaola.pdf
57. KXSS
<div class="ng-app">
{{constructor.constructor('alert(1)')()}}
</div>
Seit 8 Monaten gefixt.
57Donnerstag, 15. Mai 14
Ähnliche Probleme gibt es auch den meisten JavasScript-Template-Libraries, in diesem Fall
Angular.js. Die Templates erlauben zwar kein direktes eval, aber Methodenaufruf mit
Parametern - und wenn ich das so mache, habe ich faktisch auch wieder die Möglichkeit zu
evaluieren.
60. KXSS
•Professionell und schnelles Bugfixing
•Kontinuierliches Aktualisieren!
60Donnerstag, 15. Mai 14
Angular macht einen guten Job beim korrigieren von Security-Problemen. Aber auch im
Moment gibt es wieder ein paar security-Relevante Pull-Requests. Sprich: es sind
regelmässige Updates erforderlich.
62. Es gibt viele Orte, an denen eine
Code-Exekution möglich ist.
Es gibt viele Wege, wie sie
getriggert werden können.62Donnerstag, 15. Mai 14
Es gibt also wirklich viele Orte, von denen aus die XSS getriggert werden können - und nicht
nur das. Es gibt auch viele Quellen, durch die sie entstehen.
63. KXSSXSS Type 0:
Dom-based XSS
Lokal, nur im Client, ohne Server.
Deshalb hilft die Application Firewall nicht.
Meist basierend auf location.*
63Donnerstag, 15. Mai 14
Aber woher kommen die Daten, die da an den falschen Stellen ausgegeben werden?
Da unterscheidet man drei Typen. Der erste ist Type 0 XSS, auch DOM-based XSS genannt.
Der passiert rein im Browser, und damit auch schon auf statischen HTML-Files. Er braucht
auch keine Server, und Web Application Firewalls oder Pentesting bzw. Tests hilfen nicht.
Man kann sich nur direkt im Javascript schützen.
64. KXSSXSS Type 1:
Reflected XSS
Die typische XSS.
Eingabe -> Ausgabe -> Boom.
Schön zu testen.
Die nächste URL heilt den XSS.
64Donnerstag, 15. Mai 14
Der bekannteste Typ, unter dem auch gemeinhin XSS verstanden wird, ist der XSS Typ1, der
reflektierte XSS. Meist gibt es hier eine Eingabe und gleich auf der nächsten Seite eine
Ausgabe - zB bei Formularen. Er ist nur für denjenigen sichtbar, dessen Browser auch den
Ursprungsrequest abgeschickt hat. Der Schutz passiert meist auf der Serverseite.
65. KXSSXSS Type 2:
Persistent XSS
Wie reflektierter XSS, aber gespeichert.
Auch für andere Nutzer sichtbar, kann viral
werden.
65Donnerstag, 15. Mai 14
Der dritte Typ ist der aggressivste, der Persistente XSS. Der passiert, wenn ich zB in ein
Forum einen XSS einschleusen kann, der dann von anderen Nutzern auch gesehen wird. Oder
XSS in einem Chat.
66. KXSSXSS Type X:
Somewhere Else
Eingebettetes remote.js
Externe JSONPs
Daten aus der Datenbank
Handschrift auf der Überweisung
66Donnerstag, 15. Mai 14
Und es gibt natürlich beliebige andere Quellen, von denen meine Applikation die Daten
bekommt.
67. M
Typosquatting
XSS
1. Registrier die Domain googlesyndicatio.com
2. Erzeuge ein file http://pagead2.googlesyndicatio.com/
pagead/ads
3. 12.000 Aufrufe pro Tag
4. Beefproject zur Steuerung des Botnets.
67Donnerstag, 15. Mai 14
Und es gibt natürlich beliebige andere Quellen, von denen meine Applikation die Daten
bekommt.
68. KXSSRich Internet
Applications
Bei Single Page Applications ist jeder XSS
persistent, weil keine Heilung mehr durch
einen URL-Wechsel stattfindet.
68Donnerstag, 15. Mai 14
Das gemeine an allen drei Typen ist, dass das inzwischen für uns meist fast egal ist. Denn bei
den Single-Page-Applications, die wir normalerweise schreiben, hilft es nichts mehr - es
bleibt immer der gleiche Seitenscope bestehen, und damit ist jeder XSS, zumindest für die
Zeit der Session, persistent.
69. KMXSS
Was passiert bei
invalidem XML?
Und bei
invalidem HTML?
69Donnerstag, 15. Mai 14
Was passiert denn im Regelfall, wenn ich ein System mit XML füttere, das krude Syntaxfehler
enthält? Genau, es wirft eine Fehler und die Weiterverarbeitung wird gestoppt. Und wie sieht
das bei einer HTML-Seite aus? Exakt, die toleriert das im Regelfall. Weil sie auf feinen
Heuristiken arbeitet.
70. KMXSS
Es steht das drin,
was gemeint war.
70Donnerstag, 15. Mai 14
Die wollen nicht nur überall JavaScript executen, sondern die wollen auch aus jedem Syntax
etwas nützliches machen. Klar, wer die Anfänge auf Geocities mitbekommen hat - da war mit
sauberem Syntax nichts zu holen.
71. KMXSS
Demotime!
Idee, Konzept, sonstiges:
alles geklaut bei Mario Heiderich
71Donnerstag, 15. Mai 14
Demo!
file:///Users/johann/javascript/innerhtml_test.html
Siehe http://de.slideshare.net/x00mario/the-innerhtml-apocalypse
72. KMXSS
HTML im Browser != geschriebenes HTML
•abhängig von Browserversion
•abhängig von Browsermode
•abhängig von Position im HTML
72Donnerstag, 15. Mai 14
Was lernen wir daraus? Es kommt nicht darauf an, was wir selbst als JavaScript schreiben,
sondern es kommt darauf an, was der Browser daraus macht.
73. KMXSS
MXSS und
JavaScript-Libraries
boykottieren
Blacklisting
73Donnerstag, 15. Mai 14
Und damit haben wir das Problem: es ist Blacklisting gar nicht möglich zu sehen was von
JavaScript-Libraries als neue Funktionalität eingeführt wird, und es ist auch nicht möglich zu
voherzusehen, welcher Syntax vom Browser als interpretierbar angesehen wird.
75. Lokaler Rechner
75Donnerstag, 15. Mai 14
Aber nicht nur da hatte der Herr von Neumann einen Vorteil. Bei ihm war das noch einfach. Es
gab nämlich nur einen Rechner, und der war trusted. Weil jemand den Schlüssel zu dem
Raum hatte, in dem der Rechner stand. Und nur der kam an den Rechner ran. Also durfte der
machen, was er will.
76. 76Donnerstag, 15. Mai 14
Beim Browser sieht das anders aus - da habe ich zwar meinen lokalen Client, dem ich zwar
prinzipiell vertraue - aber dieser führt Code aus, der aus dem Internet kommt - und dem ich
meistens nicht vertrauen. Deshalb wird JavaScript ja auch in einer Sandbox ausgeführt.
Und meist habe ich Daten und JavaScript von verschiedenen Quellen auf, die wiederum
andere Quellen einbinden können - dementsprechend kann ich dem, was im Browser
passiert, nie wirklich trauen. Deshalb wurde HTTPs eingeführt, damit ist wenigstens - jenseits
der NSA - die Authentizi
77. •2.5 Milliarden Browser-Clients
•1 Milliarde Smartphones
•Private Daten im Browser
•Bankdaten im Browser
•Milliardensummen in Transaktionen
Largest Attack
Surface Ever
77Donnerstag, 15. Mai 14
Und die Grafik von eben gibt es nicht nur einmal. Sondern endlos oft. 2.5 Milliarden Clients
werden genutzt, inzwischen fast genausoviele Smartphones. Jeder hat inzwischen mehr
private Informationen im Browser als im Tagebuch. Mehr Geld über Online-Transaktionen
verwaltet als über Unterschriften.
78. Risikobewertung
•Damage - how bad would an attack be?
•Reproducibility - how easy is it to reproduce the attack?
•Exploitability - how much work is it to launch the attack?
•Affected users - how many people will be impacted?
•Discoverability - how easy is it to discover the threat?
The most dangerous
job on earth
78Donnerstag, 15. Mai 14
Wenn man eine Risikobewertung über den Browser als Plattform macht, kommt man zu ganz
interessanten Ergebnissen. Damage: Wer hat kritische Daten im Browser? Private Daten?
Bankdaten? Transaktionen wie online-Einkäufe? Kreditkartendaten?
Reproduzierbarkeit gut, weil man im Target selbst evaluieren kann. Exploitability: ich brauche
die Leute auf einer Website von mir. Affected: alle, die einen Browser im Internet nutzen.
Discoverability: Im Regelfall einfach.
79. Risikobewertung
„NSA zahlt 25 Millionen
US-Dollar für Zero-Day-Exploits“
79Donnerstag, 15. Mai 14
Quelle: http://www.forbes.com/sites/andygreenberg/2012/03/23/shopping-for-zero-days-
an-price-list-for-hackers-secret-software-exploits/
80. Browser Security
•kein Zugriff auf das Filesystem
•kein lesender Zugriff auf andere Hosts
•das aktuelle HTML-Dokument lesen / schreiben
•den Browser steuern
•Same-Origin-Policy:
•Freier Zugriff auf Daten vom gleichen Host
•Interaktion mit Plugins ist erlaubt
•Browserrechte werden vererbt
JavaScript Sandbox
80Donnerstag, 15. Mai 14
Genau deshalb implementiert JavaScript eine Sandbox. Typische Fähigkeiten anderer
Programmiersprachen - Dateien öffnen, Netzwerkverbindungen aufbauen, Schreiben - sind
verboten.
81. Same
Origin Policy
•HTML der aktuellen Seite ist manipulierbar
•Erkennung der Browser-IP per WebRTC
•nmap für Arme: Host- und Portscanning
•über Iframes, Img-Tags, JavaScript, ohne
JavaScript über Timing von <link>-Includes:
<img src=“http://192.168.2.1:80/“
onError=“stoptimer(“192.168.2.1“, 80);“ />
81Donnerstag, 15. Mai 14
Die Sandbox ist ein hervorragendes Konzept, aber sie leidet darunter, ausgerechnet in einen
Browser eingebaut zu sein. Denn der erlaubt für jede Funktionalität 8 verschiedene Wege.
82. Same
Origin Policy
•Dictionary-Attacken auf das Intranet
(„fritz.box“ anyone?)
•Erkennung von Devices und vorhandener Logins über URLs
•Breite Angriffe (zB Drive-By-Pharming) bei CPM 0.2 US$
•Welche Links kommen aus dem Cache?
82Donnerstag, 15. Mai 14
Diesen Angriff kann man natürlich noch weiter treiben - indem man etwa Dictionaries
benutzt. Wer hat in seinem Heimnetzwerk einen Host namens „Fritz.box“ ? Wer hat in seinem
Firmennetzwerk einen Host namens Jira? Diese Timing-Attacken kann ich auch auf Seiten
machen, die normalerweise hinter einem 403 sein. Oder die eingeloggt lange brauchen, weil
sie komplexe grafiken enthalten, und nicht eingelogged sehr schnell sind, weil nur eine
Fehlerseite auftaucht. Ich kann mir Werbung kaufen und diese Scripte bei 100.000 Leute
83. KXSS
var handle =
window.requestAnimationFrame(callback);
Nutzen um die Frame Rate auszurechnen
Über -moz-element iframe als vergrösserten
Background für ein <div> nutzen
teuren Morphology-Filter über einzelne
Pixel legen und Frame Rate messen
Pixel Perfect Timing
83Donnerstag, 15. Mai 14
Im vergangenen Jahr ist dieser Bereich deutlich professioneller geworden. Durch die grossen
CPU-Reserven der Clients und die modernen Grafik-Filter-Fähigkeiten der Browser kann man
Attacken fahren, die vorher so nicht möglich gewesen sind. Und so geht Pixel Perfect Timing
als Attacke:
84. KXSS
Pixel Perfect Timing
http://www.contextis.com/files/Browser_Timing_Attacks.pdf
84Donnerstag, 15. Mai 14
Hier sehen wir wie das funktioniert - links oben der Originale frame, rechts das div mit der
Kopie, unten links ein Frame mit Treshhold als Filter, und rechts unten ein einzelner Pixel -
und über diesen wird die Framerate gemessen. Damit bekommt man ein pixelgenaues Abbild
der Originalseite. Und darüber kann man OCR machen. Damit kann ich auch die Daten
fremder Frames auslesen, bis hin auf den Sourcecode.
85. Cross Site
Request Forgery
„Sea Surf“
„Anfragenfälschung mit
vorhandener Authentizierung“
85Donnerstag, 15. Mai 14
Das Problem hinter Pixel Perfect Timing ist, dass ich zwar nicht auf die Daten der anderen
Seite zugreifen kann, aber die gleichen Ressourcen nutze. Und das gilt nicht nur für die CPU
und die Grafikkarte, sondern auch für die Cookies und die Authentizierung. Ich kann zwar
nicht auf die Cookies der anderen Domain zugreifen, wenn ich meine Browser aber auf diese
Seite steuere, werden die Cookies mittransferiert. Also baue ich ein falsches Formular, das
auf die andere Seite zeigt, und sende es mittels JavaScript automatisch ab - und die
Authentifikation bleibt erhalten.
86. fCSRFCross Site
Request Forgery
Schutzmaßnahmen:
Referercheck (nicht ausreichend)
Token-Authentifizierung
86Donnerstag, 15. Mai 14
Gegen Cross Site Request Forgery schützt man sich in ganz schlecht mit einer Verlagerung
von GET auf POST, in etwas weniger schlecht mit einem Referer-Check, den man mit etwas
geschick umgehen kann, und korrekt mit einer Token-authentifizierung, der mit dem
Formular mitgeliefert wird und nur meinem Client und dem Server bekannt ist.
87. fCSRFCross Site
Request Forgery
Jeder XSS boykottiert
CSRF-Protection
87Donnerstag, 15. Mai 14
Da kommen wir aber auch gleich zu unserem Problem - wenn meine Seite einen XSS enthält,
dann kann genau dieser Token bequem ausgelesen werden - und dadurch ein falscher
Request hergestellt werden, und im Browser des Clients angeschickt werden. Der XSS muss
noch nicht einmal auf der Korrekten Seite sein - das Formular mit dem Token kann ich dank
Same Origin Policy ja auch direkt mit xmlhttprequest auslesen.
88. How to fix it
client side.
Vermeidung von :
Inline JavaScript
*.innerhtml ändern
eval();
document.write();
88Donnerstag, 15. Mai 14
Die Fixes auf der Java-Seite haben wir schon bei den Escapings besprochen, die sind
vorhanden und nutzbar. Auf der JavaScript-Seite selbst sieht das ein bischen anders aus. Ich
brauche eine Policy von Funktionen die ich vermeide.
89. How to fix it
client side.
Alte Libraries (json.js,
jquery) updaten - http://
bekk.github.io/retire.js/
Auch wenn Google sie noch
hostet ...
Statt Compiler:
jslint und jshint nutzen
89Donnerstag, 15. Mai 14
Alte Libraries sollten tatsächlich aktualisiert werden. Es gibt dort viele einfach zu nutzende
Bugs, siehe die jquery-Beispiele. Weil JavaScript so eine tolerante Sprache ist, braucht man
automatisierte Build-Code-Inspections wie jshint oder jslint.
90. How to fix it
jquery side.
Niemals untrusted
Input in die Sinks:
JQuery(), $(), $().html,
$().before(), $().after,
$().prepend, $().append
90Donnerstag, 15. Mai 14
Bei Jquery sollte man wissen, welchen Funktionen man trauen kann und welchen nicht - also
welche Sinks sind und welche nicht.
All diese Funktionen sollte nicht mit User-Input gefüttert werden.
91. How to fix it
server side.
Content-Security-Policy: script-src ‘self‘
X-Content-Security-Policy: script-src ‘self‘
X-WebKit-CSP: script-src ‘self‘
91Donnerstag, 15. Mai 14
Der erste Header ist für neue Firefox und Chrome, der zweite für alte Firefox und IE10, der
dritte für Webkit. Achtung: die machen in der Konfiguration alle schlechte JS-Libraries wie
etwa jquery kaputt, weil diese eben eval() brauchen - und das wird hier deaktiviert.
Der Header macht aus JavaScript wieder das, was man 1996 hätte gleich machen sollen.
Leider wird es von Spring selbst immer noch nicht supportet, ist aber im Spring Security 4.0
Backlog.
92. How to fix it
server side.
Content-Security-Policy: default-src ‘self‘
<img src=“bla“ onerror=alert(1)>
Content-Security-Policy: default-src ‘self‘ ‘unsafe-inline‘
<img src=“bla“ onerror=alert(1)>
Content-Security-Policy: default-src self; report-uri http://
reportcollector.example.com/collector.cgi
92Donnerstag, 15. Mai 14
Im Default deaktiviert der Header zB JavaScript in URLs, in inline <script>-tags, in Event-
Handlern und Style-Elementen. Man kann den Header auch dazu nutzen Violations - und
damit versuchte XSS - zu loggen. Oder einfache um seine Anwendung davon zu befreien :-).
93. How to fix it
server side.
CSP deaktivieren:
<meta http-equiv="Content-Security-Policy"
content="default-src 'none'">
injecten.
93Donnerstag, 15. Mai 14
Und natürlich gibt es auch wieder einen Weg drum herum. Denn jeder Header kann auch
noch mal im <head>-Bereich der HTML-Seite überschrieben werden. Also kann ich damit
den Header auch wieder downgraden. Aber wenn das eigene Framework das von sich aus
nicht unterstützt ist das eine gute Alternative.
94. Was die Zukunft
bringt
Content-Security-Policy und Freunde
lösen die Designfehler von JavaScript
HTML5 enthält einen Parser-Standard
der von allen Browsern implementiert
werden soll.
Security ist seit 2013 ein Thema der
JavaScript-Libraries
EcmaScript 6 unterstützt Module
Loaders mit global & state isolation,
private properties, Linting
94Donnerstag, 15. Mai 14
Faktisch befinden wir uns bei JavaScript gerade auf dem Weg zur Reife. Das heisst zum einen
dass die JavaScript-Entwicklung selbst besser wird, und vor allem das viele der schlechten
Design-Entscheidungen abgelöst werden können. Optional, denn man will ja
Abwärtskompatibel sein.
95. Noch Fragen?
Slides inkl. Fliesstext unter
http://slideshare.net/johannhartmann
Danke!
95Donnerstag, 15. Mai 14
97. ZNode.js
Viele Sinks:
eval(),ChildProcess.*, Cluster.*,fs.*,
http.*, net.*, process.*, dgram.*
Zugriff auf Netzwerk, Filesystem,
Prozesse
97Donnerstag, 15. Mai 14
In node.js gibt es sehr viele Funktionen, die Probleme erzeugen können, wenn ihnen
unvalidierter Code übergeben wird. Natürlich gibt es diese Funktionen auch in allen anderen
Sprachen, aber bei JavaScript ist man sie bisher nicht gewohnt - und achtet dementsprechend
weniger auf die Risiken dahinter.
98. ZNode.jshttp.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello Worldn');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
98Donnerstag, 15. Mai 14
Und wir haben die klassischen JavaScript-Probleme - diesen Code kennt vermutlich jeder, mit
ihm erzeuge ich einen neuen node-basierten HTTP-Server. Aber weil es JavaScript ist, kann
ich mit einer Code Injection die vollständige Infrastruktur der Sprache boykottieren.
99. ZNode.js
var http = require('http');
oldfunc = http.createServer;
http.createServer=function (myfunc) {
console.log('Hijacking createServer');
newfunc = function (req, res) {
result = myfunc(req, res);
console.log('MITM Request:');
console.log(req);
console.log('MITM Response:');
console.log(res);
return result;
}
return oldfunc(newfunc);
}
99Donnerstag, 15. Mai 14
Und das ist der Code, mit dem ich Create-Server so umschreibe, dass ich ich allen Verkehr zu
einer dritten Partei umleiten kann. Genauso wie ich window.alert umschreiben kann kann ich
auch http.createServer umschreiben.
102. ZNode.js
Authenticated only by E-Mail
ca 30.000 Packages, no Security-Checks
Sinks:
zB 1686*Spawn()
9518*eval()
3977*writeFile()
Average Quality is low
102Donnerstag, 15. Mai 14
Kommen wir zu einem ganz dunklem Kapitel.
NPMs sind einer der wichtigsten Gründe für das enorme Wachstum von Node. Und genau die
offene Infrastruktur, die zur schnellen und weiten Verbreitung führte, ist vom Security-
Standpunkt her ein Problem. Denn auch hier gilt das Appstore-Phänomen: man vertraut der
Absenderadresse, auch wenn sie eigentlich gar kein Vertrauen verdient - denn jeder von uns
kann jederzeit ein Package einstellen, ohne jenseits seiner E-Mail-Adresse authentifiziert zu
werden.
103. ZNode.js
Support für typische Security-Features:
- node-validator für validation & sanitizing
require('validator').sanitize(mystr).xss();
- express csrf middleware
app.use(express.csrf());
103Donnerstag, 15. Mai 14
Für die normalen Security-Anforderungen sind die meisten Pakete vorhanden, beide auch im
express-Umfeld vorhanden.
104. ZNode.js
node-validator Sanitizer:
Blacklister, also gibt es Workarounds:
<!DOCTYPE x[<!ENTITY x SYSTEM "http://html5sec.org/test.xxe">]><y>&x;</y>
und in test.xxe: <script xmlns="http://www.w3.org/1999/xhtml">alert(1)</script>
104Donnerstag, 15. Mai 14
Der Validator ist der Rewrite der Code-Igniter Infrastruktur und ok. Die Validator-Funktionen
sind gut, und die Sanitizer-Funktionen - wie jede Blacklist - unvollständig und es existieren
Workarounds.
105. ZNode.js
node-secure:
•schützt globals
•tracks eval()
•secureMethods schützt vor Überschreiben
•securePrivates verhindert Enumeration•
105Donnerstag, 15. Mai 14
Der Validator ist der Rewrite der Code-Igniter Infrastruktur und ok. Die Validator-Funktionen
sind gut, und die Sanitizer-Funktionen - wie jede Blacklist - unvollständig und es existieren
Workarounds.
106. ZNode.js
SQL-Injections:
nodejsdb solide, inklusive Parameter binding
Aber: Whitelisting von Bezeichnern und SQL-
Syntax trotzdem erforderlich
106Donnerstag, 15. Mai 14
Auch was die Basisinfrastruktur angeht sieht es nicht so schlecht aus - das nodejsdb mysql
Interface macht zB auch einen guten Eindruck. Ich muss natürlich auch nicht-bindbaren
Syntax, der in die Query geht validieren - sonst sind wieder SQL-Injections oder blind SQL-
Injections möglich.
Aber wie gesagt, das sind nur 3 von 30.000 Modulen, und gerade die selten genutzten
Module sind nicht wirklich vertrauenswürdig.
107. ZNode.js
ReDOS-Attacken: existierende reguläre
Ausdrücke so füttern, dass sie beliebig viel
CPU brauchen.
Beispiel:
var match = /^(a+)+$/.exec('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!');
Blockiert den Server > 10 Sekunden.
107Donnerstag, 15. Mai 14
108. ZNode.js
Wenn ich ein eval() im Server habe ...
process.kill(process.id);
require(‘fs‘).writeFileSync(‘/tmp/rootkit‘, data, ‘base64);
require(‘child_process‘).spawn(‘/tmp/rootkit‘);
108Donnerstag, 15. Mai 14
109. ZNode.js
Node.js auch auf Port 80 nicht als Root!
per sudo starten und dann ...
var uid = parseInt(process.env.SUDO_UID);
if (uid) process.setuid(uid);
109Donnerstag, 15. Mai 14