JavaScript Security

Post on 29-Nov-2014

1.933 views 1 download

description

Wenn der größte Teil der Logik in JavaScript stattfindet, dann findet auch der größere Teil der Sicherheitsrisiken dort seine Heimat. Und Angreifer finden mit JavaScript eine interessante neue Umwelt, denn die Sprache selbst und auch Ihre Heimat im Browser und Node.js bringen viele neue Probleme. Und genau da setzt der Vortrag an: die verblüffenden Unterschiede von JavaScript zu anderen Sprachen, wenn es um Security geht. Die Risiken und auch die Besonderheiten von Browsern und anderen JavaScript-Engines wie Node.js. Die Securityimplikationen von JavaScript-Frameworks bishin zu speziellen Problemen wie mXSS, ReDOS und HTML5-Security.

Transcript of JavaScript Security

JavaScript SecurityRace against the clock: 102 Slides, 2 Demos

Hallo Zusammen und willkommen zum Talk über JavaScript Security.

DISCLAIMER: No JavaScript-God

But pretty good at breaking stuff.

Vielleicht noch eins vorweg - ich habe nur begrenzt viel Ahnung von JavaScript. Aber ich bin ziemlich gut darin, Dinge kaputt zu machen. Auch JavaScript, Browser, Server, you name it, i break it.

•2.5 Milliarden Browser-Clients•1 Milliarde Smartphones•Private Daten im Browser•Bankdaten im Browser•Milliardensummen in Transaktionen•Die Bitcoin-Geldbörse

Largest Attack Surface Ever

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.

KXSS

Erster und wichtigster Kandidat ist XSS. Wer weiss alles, was XSS lang heisst?

KXSSCross

Site Scripting

Genau, das sollte auch jeder Wissen.Weiss jemand, warum das so heisst? Exakt, weil die Jungs schlicht nicht nachgedacht haben.Eigentlich ist das aber ein Misnomer, weil es eigentlich nur wenig mit Cross Site zu tun hat.

KXSSJavaScript

Injection

Eigentlich reden wir über JavaScript Injection, denn das ist das, was tatsächlich passiert. Auf dem Computer lokal wäre das kein Problem - aber wir haben es eben genau nicht mit nur einem Rechner zu tun, sondern mit ganz vielen - und das macht das ganze erst möglich.

KXSS<html><head><title>JavaScript-Test</title><script src="quadrat.js" type="text/javascript"></script></head>

JavaScript kann der Browser eigentlich gar nicht direkt ausführen. Die Ausführung passiert erst dann, wenn ein Dokument das JavaScript einbettet. Und das passiert so. Und wenn es nur so ginge, dann hätten wir ein Problem weniger.

KXSS<html><head><title>JavaScript-Test</title><script src="quadrat.js" type="text/javascript"></script></head>

I WANT MOAR!

Aber diese Variante war den Jungs von Netscape damals alleine zu unpraktisch. Es wäre doch total praktisch, wenn man das Javascript auch an anderen Stellen einsetzen könnte ...

KXSS<html><head><title>JavaScript-Test</title><script type="text/javascript">alert(“Hi!“);</script></head>

Wie zum Beispiel einfach direkt im Script Tag. Ok, das lag auf der Hand, aber ab dem Moment gibt es ab ... wäre es nicht auch super, wenn man zum Beispiel ...

KXSS<a href=“javascript:alert(/Hi!/);“>Click me</a>

Einfach URLs nutzen könnte, um JavaScript auszuführen???

KXSS<meta http-equiv=“refresh“ content=“0;url=“javascript:alert(1);“>

Hey, das wäre cool. Schliesslich können wir URLs fast überall nutzen. Und da geht das dann auch.

KXSS<input value=“12“ onmouseover=“alert(1);“>

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.

KXSS<script>xss = “alert(1);“;eval(xss);</script>

Und, weil wir schliesslich Informatiker sind: das sollte auch Meta und Rekursiv können. Natürlich muss JavaScript auch JavaScript ausführen können.

KXSS

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.

KXSSDas ist

unpraktisch!Das ist zwar auf der einen Seite, irgendwie total cool, dass ich das überall verwenden kann, auf der anderen Seite aber massiv unpraktisch.

KXSSFür den Browser sindDaten, Code und Darstellung das gleiche

Denn: Alles ein langer String.. Weil unsere Daten, unsere Darstellung und unser Code für den Browser das gleiche sind.

KXSSIch wollte doch nur

Daten schreiben!

Und genau da kommen unsere Probleme her - ich wollte als Entwickler nur Daten oder Layout-Elemente erzeugen. Und der Browser, die Sau, hat sich entschlossen, meine Daten ganz stumpf als Executable Code zu nutzen.

KXSS<p>Name: Hartmann</p>

<p>Name: Hartmann<script>alert(1);</script></p>

Das ist der Klassiker der Hacker-Formular-Tourette: eigentlich wollte ich nur meinen Namen eingeben, irgendwie kam dann aber ein ganz anderer String heraus, und der machte diesen Unsinn. Eigentlich sollten da nur Daten stehen, keine Ahnung, warum der Browser da jetzt Unsinn macht.

KXSS<script>plz = 80331;<script>

<script>plz = 80331;alert(1);<script>

Auch das passiert: Da wollte ich meine Javascript nur die Postleitzahl des Nutzers in die Hand geben, und durch einen doofen Typo hat es JavaScript erkannt. Weiss jemand wie ich es richtig escaped hätte? Wieder hätte ich eigentlich nur Daten haben wollen.

KXSS<input type=text value=“Hartmann“>

<input type=text value=“Hartmann“ AUTOFOCUS onfocus=“alert(1);“>

Hier wollte ich meinem Formularfeld nur sagen wie ich heisse. Dieses mal habe ich mit dem Typo aus Versehen gleich HTML5 gemacht, und schwupps, war da auch schon wieder ein Alert;

KXSSXSS Type 0:

Dom-based XSSLokal, nur im Client, ohne Server.Deshalb hilft serverside Mitigation nicht.Meist basierend auf location.*

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.

KXSSXSS Type 1:

Reflected XSSDie typische XSS.Eingabe -> Ausgabe -> Boom.Schön zu testen.Andere Seite heilt den XSS.

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.

KXSSXSS Type 2:

Persistent XSSWie reflektierter XSS, aber gespeichert.Auch für andere Nutzer sichtbar, kann viral werden.

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.

KXSSXSS Type X:

Somewhere ElseEingebettetes remote.jsExterne JSONPsHandschrift auf der Überweisung

Und es gibt natürlich beliebige andere Quellen, von denen meine Applikation die Daten bekommt.

KXSSRich Internet Applications

Bei Single Page Applications ist jeder XSS persistent, weil keine Heilung mehr durch einen URL-Wechsel stattfindet.

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.

KXSSEscaping FTW!

Also wurde zunächst einmal escaped. Wer setzt hier $.html() in Jquery ein, um Output zu escapen?

KXSS<p>Name: Hartmann&gt;script&lt;alert(1);&gt;/script&lt;</p>

escapeHtml(“Hartmann<script>alert(1);</script>“);

Ich nehme hier mal die Escape-Funktion aus Mustache, vom Jan Lehnhardt.Das klappt tatsächlich, wie cool!

KXSSescapeHtml(“Hartmann\“ AUTOFOCUS onfocus=\“alert(1); “);

<input type=text value=“Hartmann&quot; AUTOFOCUS onfocus=&quot;alert(1);“>

Heja, der klappt ja auch! Endlich habe ich eine Escape-Funktion, die Universell ist...

KXSS<script>plz = 80331;alert(1);<script>

escapeHtml(“80331;alert(1) “);

Und schauen wir uns noch mal das JS-Beispiel direkt an - das gilt btw. auch für alles, was direkt in einem Exekutierbaren Scope landet, also auch events etc. Da funktioniert das nicht weil wir dazu hätten „;“ escapen müssenDas gleiche gilt für ausgaben in JavaScript Events.

KXSSUniverselles Escaping

funktioniert nicht.Fazit: Universelles Escaping funktioniert nicht.

KXSSBlacklists ftw

Also wurde zunächst Blacklisting erfunden. Sprich: ich gucke nach bösen Sachen und filtere sie heraus. Jemand hier, der Blacklists einsetzt? PHPIDS? Validator aus Node.js?

KXSS<p>Name: Hartmann<script>alert(1);</script></p>

<p>Name: Hartmannalert(1);</p>

Blacklists sollten die gefährlichen Ausdrücke entfernen, so dass kein JavaScript mehr ausgeführt werden kann. Also wurden die einfach entfernt.

KXSS<p>Name: Hartmann<scr<script>ipt>alert(1);</scri<script>pt></p>

<p>Name: Hartmann<script>alert(1);</script></p>

Darauf haben die Hacker dann reagiert, indem sie einfach das, was entfernt wird, wieder ergänzt haben. Das hat nur so mittel geklappt. Danach sind die aber besser geworden, und laufen heute so lange über einen String, bis sie nichts mehr finden.

KXSS<p>Name: Hartmann<scr<script>ipt>alert(1);</scri<script>pt></p>

<p>Name: Hartmann[removed]alert(1); [removed] </p>

Inzwischen sind die natürlich auch besser geworden, und im regelfall - zB bei node.js validator - sieht das so aus.

KXSS<script>plz = 80331;<script>

<script>plz = 80331;alert(1);<script>

Dieses Ding bleibt trotzdem unangetastet. Ok, bei einigen Blacklists fliegt alert raus ....

KXSS<script>plz = 80331;<script>

<script>plz = 80331;prompt(1,1);<script>

... da muss man dann prompt(1,1) zum testen nehmen :-).

KXSSUniverselles Blacklisting

funktionert nicht.Fazit: Universelles Blacklisting funktioniert auch nicht.

KXSSOk, Escaping geht nicht, Blacklisting geht nicht.

Aber richtiges Escaping funktioniert schon noch, oder?

Das ist ja schon mal nicht so gut. Aber sind wir damit schon am Ende?

KMXSSThe innerhtml

ApocalypseNatürlich nicht, das wird noch eins komplizierter. Und zwar weil Browser tolerant sind. Die wollen nicht nur überall JavaScript executen, sondern die wollen auch aus jedem Syntax etwas nützliches machen.

KMXSSEs steht das drin,

was gemeint war.Natürlich nicht, das wird noch eins komplizierter. Und zwar weil Browser tolerant sind. 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.

KMXSSDemotime!

Idee, Konzept, sonstiges: alles geklaut bei Mario Heiderich

Demo! file:///Users/johann/javascript/innerhtml_test.htmlSiehe http://de.slideshare.net/x00mario/the-innerhtml-apocalypse

KMXSSHTML im Browser != geschriebenes HTML

•abhängig von Browserversion•abhängig von Browsermode•abhängig von Position im HTML

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.

KXSSAre we done

yet?Ok, sind wir jetzt endlich mit den ganzen Problemen durch?

KXSSNope.

Klar gibt es noch mehr!

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>

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.

KXSSVorher galt:

Attribut mit on* -> Triggert JavaScript

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.

KXSS<div class="ng-app">{{constructor.constructor('alert(1)')()}}</div>

Ä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.

KXSS<div class="ng-app">&#x7b;&#x7b;constructor.constructor('alert(1)')()&#x7d;&#x7d;</div>Jetzt könnte man natürlich sagen: hej, dann filtern wir einfach auf {{ .. aber leider geht auch das in die execution.

KXSS<b data-ng-app data-ng-style="constructor.constructor('alert(1)')()" />

Und nicht nur direkt im Template-Text wird executed, wie bei Dojo kann ich auch direkt im Attribut JavaScript triggern.

KXSS

Und nicht nur da spielen die Libraries eine Rolle. Wer setzt alles Jquery ein? (Jetzt sollten sich alle melden)

KXSS

Da steht ja nicht umsonst „write less, do more“ drunter. Das passiert tatsächlich.

KXSS$()

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.

KXSS$()

Aber das bedeutet auch, dass man nicht immer weiss, was passiert. Und das ist ein Problem.

KXSSSink: eine Funktion, die ein Risiko darstellt,

wenn ihr nicht vertrauenswürdiger Input übergeben wird.

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.

KXSS$() ist eine Sink$("<img src='dd' onerror='alert(1)'>");

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

KXSSOk, aber

ist das wirklich ein Problem?

Da stellt sich natürlich die Frage - ist das wirklich ein Problem?

KXSSWenn JavaScript

ausgeführt werden kann, dann ist das vollständige Vertrauen

im aktuellen Kontext zerstört.

Ja, ist es. Das erste liegt an der Sprache selbst. Die Sprache erlaubt die Manipulation und das Überschreiben von allem, auch von den Browsereigenen Objekten und Methoden.

KXSS

Ich brauche bloss window.alert(); auf eine neue Funktion zu binden, und schon passiert etwas ganz anders wenn ich einen alert() triggere. Das gleiche gilt natürlich auch für Objekte wie xmlhttprequest.

KXSS

Seiteneffekte

Same Origin PolicySandbox

Und das ist nicht das einzige Problem. JavaScript läuft zwar in der Sandbox und kann durch die Same-Origin-Policy bzw. durch Cross-Domain Policies nicht auf alles zugreifen, aber auch ohne Zugriff gibt es Seiteneffekte.

KXSSCSRF

Mein JavaScript erbt die Browsrechte anderer Tabs, wenn

ich mit Ihrem Host interagiereDer bekannteste Seiteneffekt in JavaScript ist Cross Site Request Forgery, oder auch kurz Sea-Surf. Wenn das JavaScript auf meiner Seite URLs auf einer anderen Seite aufruft, wenn es Formulare auf die andere Seite abschickt, dann bekommt dieser Request automatisch die Cookies, die HTTP-Authentifizierung dieses Host verliehen. Die Vorteile sind klar - ich kann auf eine andere Seite verlinken, und wenn ich dort eingeloggt war bleibe ich es auch.

KXSSErkennung 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);“ />

Intranet

KXSSDictionary-Attacken auf das Intranet

Url-basierte Erkennung von Devices und Login-Status

Drive-By-Pharming auf Hightrafficsites

Intranet

K XSSvar handle = window.requestAnimationFrame(callback);

damit die Frame Rate auszurechnen

Über -moz-element/webkit-box-reflect iframe als vergrösserten Background für ein <div> nutzen

teuren Morphology-Filter über einzelne Pixel legen und Frame Rate messen

Pixel Perfect Timing

KXSSPixel Perfect Timing

http://www.contextis.com/files/Browser_Timing_Attacks.pdfHier 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.

KXSSGeht natürlich auch mit view-source: urls im Chrome

Iframes-Buster vsFacebook-Comments/Likes wollen embedded werden

OCR funktioniert

Pixel Perfect Timing

KXSSDemotime!

http://beefproject.com/

1. Neuer Browserhttp://whatismyipaddress.comIP notieren2. Blog-URLhttp://blog.mayflower.de3. in http://beef.mayflower.de/ui/panel einloggen4. Links die Zombies zeigen5. Rechts Log zeigen6. Meine IP raussuchen7. Detail-Seite vorstellen - alles, was einfach ohne tricks über JavaScript zu ermitteln ist, quasi Browser Capabilities 7. Rider Nutzung des Fremden Browsers als Proxy- auf der gehijackten Domain, weil Same Origin8. CommandsBrowser Domain8.1 get cookie-> session riding mit login8.2 get page hrefs8.3 alert dialog8.4 Full Page Rickroll8.5 Webcam Permission check - interesting domains8.6 Host - Get internal IP8.7 DOSer8.9 Persistence - create popunder.9.0 Phonegap & Extension exploits

CXSSExtensions,

& HTML5& Phonegap

Da sind wir auch gleich beim nächsten Thema - HTML / XSS jenseits des Browsers.

CXSSFaktisch: HTML5-Applications

Extensions

http://de.slideshare.net/kkotowicz

CXSSExtensionsPro Domain* Sonderrechten:chrome.tabschrome.bookmarkschrome.historychrome.cookies

CXSSExtensionsPro Domain* Sonderrechten:chrome.tabschrome.bookmarkschrome.historychrome.cookies

40%http://*/*

https://*/*

CXSSExtensions

Halten sich inzwischen an Content Security Policy

Aber: diverse eval()s in Libraries (mustache, underscore, jQuery template)

CXSSExtensions

Resultat: Voller Zugriff auf alle Seiten im Browser

Inkl. Cookies und LoginsFacebook, GMail, Twitter, ...

CXSSHTML5

Alte Bugs in neuen Variationen:<input onfocus=alert(1) autofocus>

<input onblur=alert(1) autofocus><input autofocus><form id=test onforminput=alert(1)>

<button form=test onformchange=alert(2)><button form=test onformchange=alert(2)>

<math href="javascript:alert(1)">CLICKME</math>

Und natürlich werden alle alten Blacklistfilter durch neue Attribute und Tags ausgetrickst.

CXSSHTML5

<input type=file directory>

Das neue Directory-Attribute im Chrome erlaubt vollen Lesezugriff auf das Verzeichnis, nachdem es ausgewählt wurde. Einfach Download anbieten, „Download to Folder“-Button machen - und schon hat man Zugriff auf das ganze Verzeichnis.

CXSSPhonegap

Capabilities über Permissions:Camera, Contacts, Files, Geolocation,

Media,...Alle Capabilities der App in XSS nutzbar

CXSSAre we done now, please?

Sind wir jetzt endlich mit den ganzen Security Problemen durch? Wer meint wir wären durch? Genau, jetzt kommen wir erst zu den Highlights.

MTyposquatting

XSS

1. Registrier die Domain googlesyndicatio.com2. Erzeuge ein file http://pagead2.googlesyndicatio.com/pagead/ads3. 12.000 Aufrufe pro Tag4. Beefproject FTW

Und noch eine letzte Geschichte aus der Kategorie „Man glaubt es nicht:“Die Jungs von der Security-Firma Securitee haben im Sommer einfach mal die Domain googlesyndicatio.com reserviert - so wie die alte Google-Ads-Domain, vor vielen, vielen Jahre,nur mit einem Typo. Da haben sie dann ein Script abgelegt.

ZXSS

How to fix it.Ok, so langsam können wir ja auch mal schauen, wie man das ganze Repariert.

ZXSSSchlicht nicht machen:

*.innerhtml änderneval();

JSON in eval();document.write();

In HTML selbst gibt es ein paar Methoden, die man nie nutzen sollte. So praktisch sie auch aussehen. Ebenfalls sollte man versuchen Libraries, die sie einsetzen, selbst einzusetzen.

ZXSSSchlicht nicht machen:

Inline <script>-JavascriptAuslagern

Komprimieren

In HTML selbst gibt es ein paar Methoden, die man nie nutzen sollte. So praktisch sie auch aussehen. Ebenfalls sollte man versuchen Libraries, die sie einsetzen, selbst einzusetzen.

ZXSSSchlicht nicht machen:

Dynamisch HTMLJS-Templates

JS-Code(!) genieren

In HTML selbst gibt es ein paar Methoden, die man nie nutzen sollte. So praktisch sie auch aussehen. Ebenfalls sollte man versuchen Libraries, die sie einsetzen, selbst einzusetzen.

ZXSSSchlicht nicht machen:

on-Eventsstatt dessen: Explizit binden: $('#main').bind("click", function(e) { alert(1) });

In HTML selbst gibt es ein paar Methoden, die man nie nutzen sollte. So praktisch sie auch aussehen. Ebenfalls sollte man versuchen Libraries, die sie einsetzen, selbst einzusetzen.

ZXSSSchlicht nicht machen:

Alte Libraries (json.js, jquery) nutzen

Auch wenn Google sie noch hostet ...

In HTML selbst gibt es ein paar Methoden, die man nie nutzen sollte. So praktisch sie auch aussehen. Ebenfalls sollte man versuchen Libraries, die sie einsetzen, selbst einzusetzen.

ZXSSSchlicht nicht machen bei JQuery:

Niemals untrusted Input in die Sinks... JQuery(), $(), $().html, $().before(),

$().after, $().prepend, $().append

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.

ZXSSSchlicht machen:

Korrekt escapen:Urls mit EncodeURI

HTML zB mit JsHtmlSanitizerWhitelists wo sie möglich sind

ZXSSContent-Security-Policy: script-src ‘self‘X-Content-Security-Policy: script-src ‘self‘X-WebKit-CSP: script-src ‘self‘

Header

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.

ZXSSContent-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)>

Header

man kann es aber gezielt, etwa für die eigenen Domain oder den JS-CDN seines vertrauens wieder aktivieren.

ZXSSCSP deaktivieren:

<meta http-equiv="Content-Security-Policy"content="default-src 'none'">

injecten.

Header

Und mit einer HTML-Injection kann ich das ganze dann doch wieder aktivieren ...

ZXSSX-XSS-Protection: 1; mode=blockX-FRAME-OPTIONS: DENY

Header

Der Internet Explorer hat sich noch mehr Features einfallen lassen, dafür wollte er ja auch zunächst nicht bei der Content-Security-Policy mitmachen. X-XSS-Protection macht ein lustiges Filtering von Eingaben und Ausgaben und adressiert vor allem Reflektive XSS. Ich kann also nicht mehr nach <script> auf google suchen, wenn das aktiv wäre.X-Frame-Options sind wiederum gut, um Clickjacking-Attacken systematisch zu stoppen, sollte man also machen, wenn man nicht partout eingebettet werden muss.

ZNode.js

Node.js Security

ZNode.jsViele Sinks:

eval(),ChildProcess.*, Cluster.*,fs.*, http.*, net.*, process.*, dgram.*

Zugriff auf Netzwerk, Filesystem, Prozesse

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.

ZNode.js

http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n');}).listen(1337, '127.0.0.1');console.log('Server running at http://127.0.0.1:1337/');

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.

ZNode.jsvar 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);}

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.

ZNode.js

npms

Kommen wir zu einem ganz dunklem Kapitel.

ZNode.jsAuthenticated only by E-Mailca 30.000 Packages, no Security-ChecksSinks: zB 1686*Spawn() 9518*eval() 3977*writeFile() Average Quality is low

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.

ZNode.jsSupport für typische Security-Features:- node-validator für validation & sanitizing require('validator').sanitize(mystr).xss();- express csrf middleware app.use(express.csrf());

Für die normalen Security-Anforderungen sind die meisten Pakete vorhanden, beide auch im express-Umfeld vorhanden.

ZNode.jsnode-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>

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.

ZNode.jsSQL-Injections:

nodejsdb solide, inklusive Parameter bindingAber: Whitelisting von Bezeichnern und SQL-Syntax trotzdem erforderlich

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.

ZNode.jsReDOS-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.

ZNode.jsWenn ich ein eval() im Server habe ... process.kill(process.id);

require(‘fs‘).writeFileSync(‘/tmp/rootkit‘, data, ‘base64);require(‘child_process‘).spawn(‘/tmp/rootkit‘);

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);

ZFazit

Danke!