it-swarm.com.de

Die beste Art, mit Sicherheit umzugehen und XSS mit vom Benutzer eingegebenen URLs zu vermeiden

Wir haben eine Hochsicherheitsanwendung, und wir möchten Benutzern die Eingabe von URLs ermöglichen, die andere Benutzer sehen.

Dies führt zu einem hohen Risiko für XSS-Hacks - ein Benutzer könnte möglicherweise Javascript eingeben, das von einem anderen Benutzer ausgeführt wird. Da wir sensible Daten speichern, ist es unerlässlich, dass dies niemals geschieht.

Was sind die besten Vorgehensweisen im Umgang damit? Ist eine Sicherheits-Whitelist oder ein Fluchtmuster allein gut genug? 

Ratschläge zum Umgang mit Weiterleitungen (beispielsweise "Dieser Link verlässt unsere Website außerhalb" auf einer Warnungsseite, bevor Sie dem Link folgen)

Gibt es ein Argument dafür, dass vom Benutzer eingegebene Links überhaupt nicht unterstützt werden?


Klärung:

Grundsätzlich möchten unsere Benutzer Folgendes eingeben: 

stackoverflow.com

Und habe es an einen anderen Benutzer ausgegeben:

<a href="http://stackoverflow.com">stackoverflow.com</a>

Worüber ich mir wirklich Sorgen mache, ist, dass sie dies in einem XSS-Hack verwenden. Das heißt sie geben ein:

alarm ('gehackt!');

So erhalten andere Benutzer diesen Link:

<a href="alert('hacked!');">stackoverflow.com</a>

Mein Beispiel ist nur, um das Risiko zu erklären. Ich bin mir bewusst, dass Javascript und URLs unterschiedliche Dinge sind, aber wenn sie die letzteren eingeben, können sie die erstere ausführen.

Sie werden staunen, wie viele Sites Sie mit diesem Trick brechen können - HTML ist noch schlimmer. Wenn sie wissen, wie sie mit Links umgehen, wissen sie auch, <iframe>, <img> und clevere CSS-Verweise zu bereinigen?

Ich arbeite in einer Hochsicherheitsumgebung - ein einziger XSS-Hack kann für uns sehr hohe Verluste verursachen. Ich bin froh, dass ich eine Regex produzieren konnte (oder einen der hervorragenden Vorschläge verwenden kann), die alles ausschließen könnten, woran ich denken könnte, aber wäre das genug?

48
Keith

Wenn Sie glauben, dass URLs keinen Code enthalten können, denken Sie noch einmal nach!

https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet

Lesen Sie das und weinen Sie.

So machen wir es beim Stack Overflow:

/// <summary>
/// returns "safe" URL, stripping anything outside normal charsets for URL
/// </summary>
public static string SanitizeUrl(string url)
{
    return Regex.Replace(url, @"[^-A-Za-z0-9+&@#/%?=~_|!:,.;\(\)]", "");
}
52
Jeff Atwood

Um einen Link "sicher" zu machen, sollten drei oder vier Schritte durchlaufen werden:

  • Unescape/Umcodierung der Zeichenfolge, die Sie erhalten haben (RSnake hat eine Reihe von Tricks bei dokumentiert.) http://ha.ckers.org/xss.html die Escaping und UTF-Kodierungen verwenden).
  • Bereinigen Sie den Link: Regexes sind ein guter Anfang - stellen Sie sicher, dass Sie den String abschneiden oder wegwerfen, wenn er ein "(oder was auch immer Sie zum Schließen der Attribute in Ihrer Ausgabe verwenden) enthält; Wenn Sie die Links nur als Verweise verwenden Zu anderen Informationen können Sie auch das Protokoll am Ende dieses Prozesses erzwingen - wenn der Teil vor dem ersten Doppelpunkt nicht "http" oder "https" ist, fügen Sie "http: //" an den Anfang an. Dadurch können Sie brauchbare Informationen erstellen Links von unvollständigen Eingaben, die ein Benutzer in einen Browser eingeben würde, und geben Ihnen eine letzte Chance, um zu versuchen, was für ein Unfug jemand versucht, sich einzuschleichen.
  • Stellen Sie sicher, dass das Ergebnis eine wohlgeformte URL ist (Protokoll: //Host.domain [: Port] [/ Pfad] [/ [Datei]] [? QueryField = queryValue] [#anchor]).
  • Prüfen Sie das Ergebnis möglicherweise anhand einer Blacklist einer Website oder versuchen Sie, es über eine Art Malware-Checker abzurufen.

Wenn Sicherheit eine Priorität ist, würde ich hoffen, dass die Benutzer in diesem Prozess ein bisschen Paranoia vergeben würden, selbst wenn es am Ende einige sichere Verbindungen wegwirft.

13
Bell

Verwenden Sie eine Bibliothek, beispielsweise die OWASP-ESAPI-API:

Lese das folgende:

Zum Beispiel:

$url = "http://stackoverflow.com"; // e.g., $_GET["user-homepage"];
$esapi = new ESAPI( "/etc/php5/esapi/ESAPI.xml" ); // Modified copy of ESAPI.xml
$sanitizer = ESAPI::getSanitizer();
$sanitized_url = $sanitizer->getSanitizedURL( "user-homepage", $url );

Ein anderes Beispiel ist die Verwendung einer eingebauten Funktion. Die Funktion filter_var von PHP ist ein Beispiel:

$url = "http://stackoverflow.com"; // e.g., $_GET["user-homepage"];
$sanitized_url = filter_var($url, FILTER_SANITIZE_URL);

Die Verwendung von filter_varermöglicht Javascript-Aufrufe und filtert Schemata heraus, die weder http noch https sind. Die Verwendung des OWASP ESAPI Sanitizer ist wahrscheinlich die beste Option.

Ein weiteres Beispiel ist der Code aus WordPress :

Da es keine Möglichkeit gibt, zu wissen, wo die URL verlinkt ist (d. H. Es könnte sich um eine gültige URL handeln, der Inhalt der URL könnte jedoch schädlich sein), verfügt Google über eine safe browse - API, die Sie aufrufen können:

Es ist aus mehreren Gründen problematisch, Ihren eigenen Regex für die Hygiene zu rollen:

  • Wenn Sie nicht Jon Skeet sind, enthält der Code Fehler.
  • Bestehende APIs haben viele Stunden zur Überprüfung und zum Testen hinter sich.
  • Bestehende URL-Validierungs-APIs berücksichtigen die Internationalisierung.
  • Bestehende APIs werden mit neuen Standards auf dem neuesten Stand gehalten.

Andere Punkte zu beachten:

  • Welche Schemas erlauben Sie (sind file:/// und telnet:// akzeptabel)?
  • Welche Einschränkungen möchten Sie dem Inhalt der URL auferlegen (sind Malware-URLs akzeptabel)?
8
Dave Jarvis

Sie geben nicht die Sprache Ihrer Anwendung an. Ich gehe dann davon aus, dass ASP.NET verwendet wird. Dazu können Sie die Microsoft Anti-Cross Site Scripting Library verwenden.

Es ist sehr einfach zu bedienen, alles was Sie brauchen ist ein Include und das ist es :)

Während Sie sich mit dem Thema befassen, warum lesen Sie nicht weiter unter Design-Richtlinien für sichere Webanwendungen

Wenn es eine andere Sprache gibt ... wenn es eine Bibliothek für ASP.NET gibt, muss es auch für andere Sprachen verfügbar sein (PHP, Python, ROR usw.).

3
balexandre

HTMLEncode die Links, wenn Sie sie ausgeben. Stellen Sie sicher, dass Sie keine javascript:-Links zulassen. (Es ist am besten, eine Whitelist der akzeptierten Protokolle zu haben, z. B. http, https und mailto.)

3

Wie wäre es, sie nicht als Link anzuzeigen? Verwenden Sie einfach den Text.

In Kombination mit einer Warnung, auf eigene Gefahr fortzufahren, kann dies ausreichend sein.

Addition - see also Soll ich HTML-Markup für ein gehostetes CMS bereinigen? für eine Diskussion über die Bereinigung von Benutzereingaben

1
warren

In meinem in JavaScript geschriebenen Projekt verwende ich diese Regex als weiße Liste:

 url.match(/^((https?|ftp):\/\/|\.{0,2}\/)/)

die einzige Einschränkung ist, dass Sie ./ für Dateien im gleichen Verzeichnis vor setzen müssen, aber ich denke, ich kann damit leben.

0
jcubic

Versuchen Sie für Pythonistas Scrapys w3lib .

OWASP ESAPI datiert vor Python 2.7 und ist im jetzt nicht mehr existierenden Google Code archiviert.

0
Zach Valenta