2009-08-23 5 views
4

Ich plane eine Web-App, mit der Benutzer ganze Webseiten auf meiner Website veröffentlichen können. Ich denke an die Verwendung von HTML Purifier, aber ich bin mir nicht sicher, weil HTML-Filter die HTLM bearbeitet und es wichtig ist, dass der HTML-Code so gepflegt wird, wie er gepostet wurde. Also habe ich mir überlegt, ein paar Regex zu machen, um alle Script-Tags und alle Javascript-Attribute wie onload, onclick usw. loszuwerden.Welche Vorkehrungen sollte ich treffen, um XSS auf vom Benutzer übermittelten HTML zu verhindern?

Ich habe vor einiger Zeit ein Google-Video gesehen, das eine Lösung dafür hatte. Ihre Lösung bestand darin, eine andere Website zu verwenden, um Javascript zu posten, damit die ursprüngliche Website nicht darauf zugreifen kann. Aber ich möchte keine neue Domain nur dafür kaufen.

+0

Vielen Dank für das Stellen dieser Frage. Das Web wäre ein viel besserer (und sicherer!) Platz, wenn jeder, der eine Web-App erstellt hat, dies vor dem Start gefragt hat. –

Antwort

3

Wenn Sie andere Möglichkeiten finden können, Benutzer Inhalte zu posten, die nicht HTML beinhalten, tun Sie das. Es gibt viele benutzerfreundliche Markup-Systeme, mit denen Sie HTML generieren können.

So denke ich einige regex machen aller Script-Tags und alle JavaScript-Attribute wie onload loszuwerden, Onclick usw.

es

Vergessen. Sie können HTML mit Regex auf keine nützliche Weise verarbeiten. Ganz zu schweigen davon, wenn Sicherheit involviert ist und Angreifer absichtlich gefälschte Markups auf Sie werfen.

Wenn Sie Ihre Benutzer davon überzeugen können, XHTML einzugeben, ist das viel einfacher zu analysieren. Sie können es immer noch nicht mit Regex machen, aber Sie können es in einen einfachen XML-Parser werfen und über die resultierende Knotenstruktur gehen, um zu überprüfen, dass jedes Element und Attribut bekanntermaßen sicher ist, und alle löschen, die nicht vorhanden sind -serialisieren.

HTML-Filter bearbeitet die HTLM und es ist wichtig, dass der HTML-Code so gepflegt wird, wie er gepostet wurde.

Warum?

Wenn es so ist, können sie es in ihrer ursprünglichen Form bearbeiten, dann ist die Antwort einfach, es auf dem Weg zu reinigen, um im Browser angezeigt zu werden, nicht auf dem Weg zur Sendezeit.

Wenn Sie müssen Benutzer geben ihre eigenen HTML-freien Eingabe - und in der Regel würde ich davon abraten - dann HTML Purifier, mit einer Whitelist-Ansatz (verbieten alle Elemente/Attribute, die nicht bekannt sind - sicher) ist ungefähr so ​​gut wie es geht. Es ist sehr, sehr kompliziert und Sie müssen es vielleicht auf dem neuesten Stand halten, wenn Hacks gefunden werden, aber es ist Straßen vor allem, was Sie sich mit Regexen hacken werden.

Aber ich möchte keine neue Domäne nur dafür kaufen.

Sie können eine Subdomäne verwenden, solange Authentifizierungs-Tokens (insbesondere Cookies) nicht zwischen Subdomänen wechseln können. (Bei Cookies können sie standardmäßig nicht als Domänenparameter auf den aktuellen Hostnamen festgelegt werden.)

Vertrauen Sie Ihren Benutzern mit Skriptfunktionen? Wenn nicht, lassen Sie sie nicht, oder Sie erhalten Angriffsskripte und Iframes auf russische Exploit-/Malware-Sites überall ...

+2

"Sie müssen es möglicherweise auf dem neuesten Stand halten, wenn Hacks gefunden werden" Dies ist ein weiterer Grund, es auf dem Weg zum Browser zu reinigen.Wenn Sie dies auf dem Weg dorthin tun, wird die Aktualisierung Ihrer Filter, um neue Angriffe zu verhindern, Sie nicht automatisch vor Angriffen dieses Typs schützen, die vorgenommen wurden, bevor der neue Filter eingesetzt wurde. –

+0

Einverstanden. Im Allgemeinen ist es in der Regel eine gute Idee, die ursprüngliche Eingabe von etwas beizubehalten, anstatt einer verarbeiteten Version. – bobince

+0

Ich kümmere mich nur wirklich um Cookies. Dieser veröffentlichte Inhalt wird nicht auf der Website gespeichert. Es funktioniert wie ein Proxy, aber es ist kein Proxy. Wenn Sie sagen, dass Cookies nicht von einer Subdomain aus zugänglich sind, dann gehe ich mit einer Subdomain. – fent

3

Stellen Sie sicher, dass der Benutzerinhalt nichts enthält, was dazu führen könnte, dass Javascript auf Ihrer Seite ausgeführt wird.

Sie können dies tun, indem Sie eine HTML-Stripping-Funktion verwenden, die alle HTML-Tags (wie von PHP) oder mit einem anderen ähnlichen Tool loswird. Neben XSS gibt es dafür viele Gründe. Wenn Sie vom Nutzer Inhalte eingereicht haben, möchten Sie sicherstellen, dass das Layout der Website nicht beeinträchtigt wird.

Ich glaube, Sie können einfach eine Subdomain Ihrer aktuellen Domain verwenden, um Javascript zu hosten, und Sie erhalten die gleichen Sicherheitsvorteile für AJAX. Keine Kekse jedoch.


In Ihrem speziellen Fall wird die <script> Tag und Javascript Aktionen Ausfiltern wahrscheinlich die beste Wahl sein.

+1

achten Sie darauf, auch <style> Tags und Stilattribute auszublenden, da der IE CSS-Ausdrücke in ihnen ausführen wird. – scunliffe

+0

entfernen Sie auch alle Inline-Event-Handler (onclick, onmouseover, ondblclick, onmouseenter, ...) alle normalen Ereignisse sowie alle proprietären IE. – scunliffe

+0

Können Sie bestätigen, dass eine Subdomain dafür geeignet wäre? Wenn ja, würde ich das lieber nutzen und Javascript erlauben, ohne den Zugriff auf Cookies. Auch das Style-Tag und -Attribut sind etwas, was für das, was ich mache, notwendig ist. – fent

5

mit Homebrew Regexes für diese Art der Sache

Ein regex wie

s/(<.*?)onClick=['"].*?['"](.*?>)/$1 $3/ 

sieht aus wie könnte es loszuwerden Onclick Ereignisse, aber man kann es umgehen mit

<a onClick<a onClick="malicious()">="malicious()"> 
vorsichtig sein

läuft die Regex auf das wird Ihnen etwas wie

<a onClick ="malicious()"> 

Sie können es beheben, indem Sie die Regex für diese Zeichenfolge wiederholt ausführen, bis sie nicht übereinstimmt, aber das ist nur ein Beispiel dafür, wie einfach es ist, einfache Regex-Desinfektionsmittel zu umgehen.

0

1) Verwenden Sie saubere einfache verzeichnisbasierte URIs, um Benutzerfeeddaten zu liefern. Stellen Sie sicher, dass Sie bei der dynamischen Erstellung von URIs für die hochgeladenen Daten, das Dienstkonto oder andere Elemente Ihrer Domain keine Informationen als Parameter an den URI senden. Dies ist ein extrem einfacher Punkt der Manipulation, der verwendet werden könnte, um Schwachstellen in der Serversicherheit aufzudecken und möglicherweise sogar Code auf Ihren Server zu injizieren.

2) Patchen Sie Ihren Server. Stellen Sie sicher, dass Ihr Server stets über die neuesten Sicherheitspatches für alle Dienste informiert ist, die auf diesem Server ausgeführt werden.

3) Alle möglichen serverseitigen Schutzmaßnahmen gegen SQL-Injektion ergreifen. Wenn jemand Code in Ihre SQL-Datenbank injizieren kann, die von Diensten auf Ihrer Box ausgeführt werden kann, wird diese Person Ihre Box besitzen.An diesem Punkt können sie dann Malware auf Ihrem Webserver installieren, um sie an Ihre Benutzer zurückzusenden, oder einfach Daten vom Server aufzeichnen und an eine böswillige Partei senden.

4) Erzwinge alle neuen Uploads in einen geschützten Sandbox-Bereich, um die Skriptausführung zu testen. Egal, wie Sie versuchen, Skript-Tags aus dem eingereichten Code zu entfernen, gibt es eine Möglichkeit, Ihre Sicherheitsmaßnahmen zu umgehen, um Skript auszuführen. Browser sind schlampig und machen alle möglichen dummen Mist, die sie nicht tun sollen. Testen Sie Ihre Einsendungen in einem sicheren Bereich, bevor Sie sie für den öffentlichen Verbrauch veröffentlichen.

5) Nach Beacons im eingereichten Code suchen. Dieser Schritt erfordert den vorherigen Schritt und kann sehr kompliziert sein, da er im Skriptcode auftreten kann, der ein Browser-Plug-in erfordert, wie z. B. ActionScript, aber ebenso eine Sicherheitsanfälligkeit wie das Ausführen von JavaScript aus vom Benutzer eingereichten Code darstellt . Wenn ein Benutzer Code senden kann, der an Dritte weitergeben kann, sind Ihre Benutzer und möglicherweise Ihr Server vollständig einem Datenverlust für böswillige Dritte ausgesetzt.

+0

Ich folge nicht ganz # 1 ... Können Sie ein (hypothetisches) Beispiel für einen Angriff auf URI-Parameter angeben, der durch die Verwendung von URIs im Pathinfo-Stil ("verzeichnisbasiert") verhindert werden könnte? –

+0

Lässt die folgende URI nehmen: „?“ http://domain.com/page.html?login=name&query=term&ordernum=1234&account=5678&dest=cart&status=vip Wenn Ihre Anwendung URIs mit einer Erzeugungs Charakter, dann haben Sie wahrscheinlich etwas Umdenken zu tun. Bewahren Sie alle Daten auf dem Server auf und geben Sie dem Benutzer nur das zurück, was sie wirklich als Inhalt auf der Seite benötigen. –

+0

Ja, aber ich sehe immer noch nicht, dass das anfälliger ist als domain.com/page/login/name/query/term/ordernum/1234/account/5678/dest/cart/status/vip. Das Problem besteht in der Menge an Informationen, die in der URL enthalten sind, und nicht darin, ob diese Informationen als Parameter übergeben werden oder ob sie als Pfadinfo übergeben werden. Abgesehen von SEO und Hässlichkeit, ist mir keine Möglichkeit bekannt, dass domain.com/?action=login schlimmer ist als domain.com/login/ - es sei denn, ich vermisse etwas, es ist nicht das "?" das ist das Problem. –

4

Der kritischste Fehler, den Leute machen, wenn sie dies tut, ist die Validierung der Dinge am Eingang.

Stattdessen sollten Sie auf dem Display validieren.

Der Kontext spielt eine Rolle, wenn festgestellt wird, was XSS ist und was nicht. Daher können Sie jede Eingabe gerne annehmen, solange Sie sie bei der Anzeige durch geeignete Reinigungsfunktionen übergeben.

Betrachten Sie, dass etwas, das "XSS" konstituiert, anders sein wird, wenn der Eingang in '&lt;a href="HERE"> im Gegensatz zu <a>here!</a> platziert wird.

Daher müssen Sie nur sicherstellen, dass Sie jedes Mal, wenn Sie Benutzerdaten schreiben, genau überlegen, wo Sie sie anzeigen, und sicherstellen, dass sie dem Kontext, in dem Sie sie schreiben, nicht entgehen können zu.

0

Sie sollten ALLE HTML-Dateien filtern und nur die Tags und Attribute, die sie sind, auf die weiße Liste setzen sicher und semantisch nützlich. WordPress ist gut darin und ich nehme an, dass Sie die regulären Ausdrücke finden, die von WordPress benutzt werden, wenn Sie ihren Quellcode suchen.