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

StackOverflow https://stackoverflow.com/questions/205923

Question

Nous avons une application haute sécurité et nous voulons permettre aux utilisateurs de saisir des URL que d'autres utilisateurs verront.

Ceci introduit un risque élevé de piratage XSS - un utilisateur peut potentiellement entrer du code javascript qu'un autre utilisateur finira par exécuter. Puisque nous détenons des données sensibles, il est essentiel que cela ne se produise jamais.

Quelles sont les meilleures pratiques en la matière? Une liste blanche de sécurité ou un modèle d’échappement est-il suffisant?

Tout conseil sur le traitement des redirections (& "; ce lien sort de notre site &"; message sur une page d'avertissement avant de suivre le lien, par exemple)

.

Existe-t-il un argument pour ne pas prendre en charge les liens entrés par l'utilisateur?

Clarification:

En gros, nos utilisateurs veulent saisir:

  

stackoverflow.com

et le transmettre à un autre utilisateur:

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

Ce qui me préoccupe vraiment, c’est qu’ils utilisent cela dans un hack XSS. C'est à dire. ils entrent:

  

alert ('piraté!');

Les autres utilisateurs obtiennent donc ce lien:

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

Mon exemple est juste pour expliquer le risque - je sais bien que javascript et les URL sont des choses différentes, mais en les laissant entrer ce dernier, ils pourraient peut-être exécuter le premier.

Vous seriez surpris de voir combien de sites vous pouvez briser avec cette astuce - HTML est encore pire. S’ils savent manipuler des liens, savent-ils également comment désinfecter <iframe>, <img> et les références CSS intelligentes?

Je travaille dans un environnement hautement sécurisé: un simple piratage XSS pourrait entraîner de très lourdes pertes. Je suis heureux de pouvoir produire un regex (ou d'utiliser l'une des excellentes suggestions proposées jusqu'à présent), capable d'exclure tout ce à quoi je pourrais penser, mais est-ce que cela suffirait?

Était-ce utile?

La solution

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

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

Lisez-le et pleurez.

Voici comment nous procédons en cas de dépassement de capacité:

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

Autres conseils

Le processus de rendu d'un lien & "; safe &"; devrait passer par trois ou quatre étapes:

  • Décompressez / ré-encodez la chaîne qui vous a été fournie (RSnake a documenté un certain nombre de trucs à l'adresse http://ha.ckers.org/xss.html qui utilise les fonctions d'échappement et UTF codages).
  • Nettoyez le lien: les expressions rationnelles sont un bon début - assurez-vous de tronquer la chaîne ou de la jeter si elle contient un " (ou ce que vous utilisez pour fermer les attributs dans votre sortie); Si vous utilisez les liens uniquement comme références à d'autres informations, vous pouvez également forcer le protocole à la fin de ce processus. Si la partie précédant les deux points n'est pas "http" ou "https", ajoutez "http: //". au début. Cela vous permet de créer des liens utilisables à partir d'une saisie incomplète comme un utilisateur le ferait dans un navigateur et vous donne une dernière chance de déclencher tout le mal que quelqu'un a tenté de se faufiler.
  • Vérifiez que le résultat est une URL bien formée (protocole: //host.domain [: port] [/ chemin] [/ [fichier]] [? queryField = queryValue] [#anchor]).
  • Vérifiez éventuellement le résultat par rapport à une liste noire de sites ou essayez de le récupérer via un vérificateur de programmes malveillants.

Si la sécurité est une priorité, j'espère que les utilisateurs pardonneront un peu de paranoïa dans ce processus, même s'il finit par jeter des liens sûrs.

Utilisez une bibliothèque, telle que l'API OWASP-ESAPI:

Lisez les informations suivantes:

Par exemple:

$url = "http://stackoverflow.com"; // e.g., 

Utilisez une bibliothèque, telle que l'API OWASP-ESAPI:

Lisez les informations suivantes:

Par exemple:

$url = "http://stackoverflow.com"; // e.g., 

Utilisez une bibliothèque, telle que l'API OWASP-ESAPI:

Lisez les informations suivantes:

Par exemple:

$url = "http://stackoverflow.com"; // e.g., 

Utilisez une bibliothèque, telle que l'API OWASP-ESAPI:

Lisez les informations suivantes:

Par exemple:

<*>

Un autre exemple consiste à utiliser une fonction intégrée. PHP filter_var fonction est un exemple:

<*>

L'utilisation de filter_var autorise les appels javascript, et les filtre régimes qui ne sont ni http ni https . Utilisation du OWASP ESAPI Sanitizer est probablement la meilleure option.

Encore un autre exemple est le code provenant de WordPress :

De plus, puisqu'il n'y a aucun moyen de savoir où l'URL est liée (par exemple, il peut s'agir d'une URL valide, mais le contenu de l'URL peut être malicieux), Google a un navigation sécurisée API que vous pouvez appeler:

Faire rouler sa propre regex pour l’assainissement pose problème pour plusieurs raisons:

  • À moins que vous ne soyez Jon Skeet, le code comportera des erreurs.
  • Les API existantes disposent de nombreuses heures d'analyse et de test.
  • Les API de validation d'URL existantes considèrent l'internationalisation.
  • Les API existantes seront régulièrement mises à jour avec les normes émergentes.

Autres points à prendre en compte:

  • Quels modèles autorisez-vous ( fichier: /// et telnet: // sont-ils acceptables)?
  • Quelles restrictions souhaitez-vous placer sur le contenu de l'URL (les URL de programmes malveillants sont-elles acceptables)?
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 consiste à utiliser une fonction intégrée. PHP filter_var fonction est un exemple:

<*>

L'utilisation de filter_var autorise les appels javascript, et les filtre régimes qui ne sont ni http ni https . Utilisation du OWASP ESAPI Sanitizer est probablement la meilleure option.

Encore un autre exemple est le code provenant de WordPress :

De plus, puisqu'il n'y a aucun moyen de savoir où l'URL est liée (par exemple, il peut s'agir d'une URL valide, mais le contenu de l'URL peut être malicieux), Google a un navigation sécurisée API que vous pouvez appeler:

Faire rouler sa propre regex pour l’assainissement pose problème pour plusieurs raisons:

  • À moins que vous ne soyez Jon Skeet, le code comportera des erreurs.
  • Les API existantes disposent de nombreuses heures d'analyse et de test.
  • Les API de validation d'URL existantes considèrent l'internationalisation.
  • Les API existantes seront régulièrement mises à jour avec les normes émergentes.

Autres points à prendre en compte:

  • Quels modèles autorisez-vous ( fichier: /// et telnet: // sont-ils acceptables)?
  • Quelles restrictions souhaitez-vous placer sur le contenu de l'URL (les URL de programmes malveillants sont-elles acceptables)?
GET["user-homepage"]; $sanitized_url = filter_var($url, FILTER_SANITIZE_URL);

Un autre exemple consiste à utiliser une fonction intégrée. PHP filter_var fonction est un exemple:

<*>

L'utilisation de filter_var autorise les appels javascript, et les filtre régimes qui ne sont ni http ni https . Utilisation du OWASP ESAPI Sanitizer est probablement la meilleure option.

Encore un autre exemple est le code provenant de WordPress :

De plus, puisqu'il n'y a aucun moyen de savoir où l'URL est liée (par exemple, il peut s'agir d'une URL valide, mais le contenu de l'URL peut être malicieux), Google a un navigation sécurisée API que vous pouvez appeler:

Faire rouler sa propre regex pour l’assainissement pose problème pour plusieurs raisons:

  • À moins que vous ne soyez Jon Skeet, le code comportera des erreurs.
  • Les API existantes disposent de nombreuses heures d'analyse et de test.
  • Les API de validation d'URL existantes considèrent l'internationalisation.
  • Les API existantes seront régulièrement mises à jour avec les normes émergentes.

Autres points à prendre en compte:

  • Quels modèles autorisez-vous ( fichier: /// et telnet: // sont-ils acceptables)?
  • Quelles restrictions souhaitez-vous placer sur le contenu de l'URL (les URL de programmes malveillants sont-elles acceptables)?
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 consiste à utiliser une fonction intégrée. PHP filter_var fonction est un exemple:

<*>

L'utilisation de filter_var autorise les appels javascript, et les filtre régimes qui ne sont ni http ni https . Utilisation du OWASP ESAPI Sanitizer est probablement la meilleure option.

Encore un autre exemple est le code provenant de WordPress :

De plus, puisqu'il n'y a aucun moyen de savoir où l'URL est liée (par exemple, il peut s'agir d'une URL valide, mais le contenu de l'URL peut être malicieux), Google a un navigation sécurisée API que vous pouvez appeler:

Faire rouler sa propre regex pour l’assainissement pose problème pour plusieurs raisons:

  • À moins que vous ne soyez Jon Skeet, le code comportera des erreurs.
  • Les API existantes disposent de nombreuses heures d'analyse et de test.
  • Les API de validation d'URL existantes considèrent l'internationalisation.
  • Les API existantes seront régulièrement mises à jour avec les normes émergentes.

Autres points à prendre en compte:

  • Quels modèles autorisez-vous ( fichier: /// et telnet: // sont-ils acceptables)?
  • Quelles restrictions souhaitez-vous placer sur le contenu de l'URL (les URL de programmes malveillants sont-elles acceptables)?

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

Vous ne spécifiez pas la langue de votre application, je présumerai donc ASP.NET et vous pouvez utiliser pour cela Bibliothèque de scripts antiterroristes de Microsoft

Il est très facile à utiliser, tout ce dont vous avez besoin est un include, et c’est ça:)

Pendant que vous êtes sur le sujet, pourquoi ne pas lire Design Instructions pour les applications Web sécurisées

Si un autre langage .... s'il existe une bibliothèque pour ASP.NET, doit être également disponible pour un autre type de langage (PHP, Python, ROR, etc.)

Pourquoi ne pas les afficher sous forme de lien? Utilisez simplement le texte.

Combiné avec un avertissement de procéder à vos risques et périls, cela peut suffire.

ajout - voir aussi Si je désinfecte HTML balisage pour un CMS hébergé? pour une discussion sur la désinfection des entrées de l'utilisateur

Dans mon projet écrit en JavaScript, j'utilise cette expression rationnelle comme liste blanche:

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

la seule limitation est que vous devez placer ./ devant les fichiers du même répertoire, mais je pense pouvoir vivre avec cela.

Pour les pythonistes, essayez le w3lib de Scrap.

OWASP ESAPI est antérieure à Python 2.7 et est archivée dans Code Google maintenant obsolète .

Vous pouvez utiliser un code hexadécimal pour convertir l’URL entière et l’envoyer à votre serveur. De cette façon, le client ne comprendrait pas le contenu au premier abord. Après avoir lu le contenu, vous pouvez décoder l'URL du contenu =? et l'envoyer au navigateur.

Autoriser une URL et autoriser JavaScript sont deux choses différentes.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top