82 votes

Meilleure façon de gérer la sécurité et d'éviter XSS avec les URL saisies par l'utilisateur

Nous avons une forte demande de sécurité et nous voulons permettre aux utilisateurs d'entrer des Url qui permettra aux autres utilisateurs de voir.

Cela introduit un risque élevé de XSS hacks - un utilisateur peut potentiellement entrer en javascript qu'un autre utilisateur se termine en cours d'exécution. Puisque nous avons des données sensibles, il est essentiel que cela n'arrive jamais.

Quelles sont les meilleures pratiques dans la gestion de cette? Est tout la sécurité de liste blanche ou d'échapper au seul motif suffisant?

Des conseils sur la façon de traiter avec les redirections ("ce lien est en dehors de notre site" et un message sur une page d'avertissement avant de suivre le lien, par exemple)

Est-il un argument pour ne pas supporter l'utilisateur a entré des liens à tous?


Précisions:

Au fond, nos utilisateurs veulent d'entrée:

stackoverflow.com

Et l'ont sortie à un autre utilisateur:

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

Ce que je vraiment vous inquiéter, c'est en utilisant cette dans un XSS hack. I. e. ils en entrée:

alert('piraté!');

Afin que les autres utilisateurs à obtenir ce lien:

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

Mon exemple est juste pour expliquer le risque, j'en suis bien conscient que javascript et les Url sont des choses différentes, mais en les laissant entrer le deuxième cas, ils peuvent être en mesure d'exécuter l'ancien.

Vous seriez étonné de voir comment de nombreux sites que vous pouvez rompre avec ce truc - HTML est encore pire. Si ils savent traiter avec des liens à faire, mais ils savent aussi à assainir <iframe>, <img> , intelligent et CSS références?

Je suis en train de travailler dans un environnement de haute sécurité - un seul XSS hack pourrait entraîner de très fortes pertes pour nous. Je suis heureux que j'ai pu produire une Regex (ou utiliser l'une des excellentes suggestions à ce jour) qui pourrait exclure tout ce que je pouvais penser, mais est-ce assez?

63voto

Jeff Atwood Points 31111

Si vous pensez que les URL ne peuvent pas contenir de code, détrompez-vous!

http://ha.ckers.org/xss.html

Lisez ça et pleurez.

Voici comment nous procédons sur 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+&@#/%?=~_|!:,.;\(\)]", "");
}
 

17voto

Bell Points 5881

Le processus de rendu d'un lien "fort" doit passer par trois ou quatre étapes:

  • Ne pas encoder/ré-encoder la chaîne que vous avez été donné (RSnake a documenté un certain nombre de tours à http://ha.ckers.org/xss.html cette utilisation s'échapper et de codages UTF).
  • Nettoyer le lien: Regexes sont un bon départ, assurez-vous de tronquer la chaîne ou de la jeter si elle contient un "(ou ce que vous utilisez pour fermer les attributs de votre sortie); Si vous êtes en train de faire les liens uniquement à titre de référence pour d'autres informations, vous pouvez également forcer le protocole à la fin de ce processus - si la partie avant le premier colon n'est pas le "http" ou "https" puis d'ajouter: "http://" au début. Cela vous permet de créer utilisable liens d'entrée incomplète comme le ferait un utilisateur saisissez dans votre navigateur et vous donne un dernier coup à ruiner tout ce mal que quelqu'un a essayé de se faufiler dans.
  • Vérifier que le résultat est bien formé URL (protocole://host.domaine[:port][/path][/[fichier]][?queryField=queryValue][#ancre]).
  • Éventuellement vérifier le résultat à l'encontre d'un site de liste noire, ou à essayer de le chercher à travers une sorte de malware outil.

Si la sécurité est une priorité, j'espère que les utilisateurs de pardonner un peu de paranoïa dans ce processus, même si elle ne finissent par jeter quelques liens sûrs.

13voto

Dave Jarvis Points 12598

Utiliser une bibliothèque, comme OWASP-ESAPI API:

Lire la suite:

Par exemple:

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

Un autre exemple est l'utilisation d'une fonction intégrée. PHP filter_var fonction est un exemple:

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

Notez que la fonction s'affiche afin de filtrer les régimes qui ne sont ni http ni https.

Encore un autre exemple est le code de WordPress:

En outre, puisqu'il n'y a aucun moyen de savoir où l'URL des liens (c'est à dire, il pourrait être une URL valide, mais le contenu de l'URL pourrait être espiègle), Google dispose d'une navigation sécurisée API, vous pouvez appeler:

Rouler votre propre regex pour l'assainissement est problématique pour plusieurs raisons:

  • Sauf si vous êtes Jon Skeet, le code comporte des erreurs.
  • Les APIs existantes ont de nombreuses heures de test et de révision derrière eux.
  • URL existante-validation Api envisager l'internationalisation.
  • L'Api doit être tenu à jour avec les nouvelles normes.

D'autres questions à considérer:

  • Ce que les régimes ne vous le permettent (sont - file:/// et telnet:// acceptable)?
  • Quelles sont les restrictions voulez-vous placer sur le contenu de l'URL (les logiciels malveillants Url acceptable)?

4voto

Patrick McElhaney Points 22093

Juste HTMLEncode les liens lorsque vous les affichez. Assurez-vous de ne pas autoriser les liens javascript: . (Il est préférable d'avoir une liste blanche de protocoles acceptés, par exemple http, https et mailto.)

3voto

balexandre Points 36115

Vous ne précisez pas la langue de votre demande, je vais donc présumer ASP.NET et pour cela, vous pouvez utiliser le Microsoft Anti-Cross Site Scripting Library

Il est très facile à utiliser, tout ce que vous avez besoin est un include et c'est tout :)

Pendant que vous êtes sur le sujet, pourquoi ne pas donné de lire sur les lignes Directrices de Conception pour les Applications Web Sécurisées

Si une autre langue.... si il y a une bibliothèque pour ASP.NET doit être disponible pour d'autres types de langage (PHP, Python, ROR, etc)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X