web-dev-qa-db-fra.com

Java Meilleures pratiques pour empêcher les scripts intersites

J'ai parcouru les dix principales vulnérabilités de l'OWASP et j'ai découvert que Cross-Site Scripting est celui que nous devons prendre des notes. Il y avait peu de solutions recommandées. L'un d'eux a déclaré qu'il ne fallait pas utiliser la validation de "liste noire" pour détecter XSS en entrée ou pour coder la sortie. La recherche et le remplacement de quelques caractères (< Et > Et d'autres caractères ou expressions similaires tels que script) sont faibles et ont été attaqués avec succès. Même une balise “<b>” Non vérifiée n'est pas sûre dans certains contextes. XSS propose un nombre surprenant de variantes qui permettent de contourner facilement la validation de la liste noire. Une autre solution a déclaré que le codage de sortie Strong. Assurez-vous que toutes les données fournies par l'utilisateur sont correctement codées par entité (HTML ou XML selon le mécanisme de sortie) avant le rendu. Alors, quelle est la meilleure façon d'empêcher les scripts intersites de valider et de remplacer l'entrée ou de coder la sortie?

32
Hoe Chin

La pratique normale consiste à échapper HTML toutes les données contrôlées par l'utilisateur pendant réaffichage dans JSP, pas pendant processing les données soumises dans le servlet ni pendant stockage dans la base de données. Dans JSP, vous pouvez utiliser JSTL (pour l'installer, déposez simplement jstl-1.2.jar dans /WEB-INF/lib) <c:out> tag ou fn:escapeXml fonction pour cela. Par exemple.

<%@ taglib uri="http://Java.Sun.com/jsp/jstl/core" prefix="c" %>
...
<p>Welcome <c:out value="${user.name}" /></p>

et

<%@ taglib uri="http://Java.Sun.com/jsp/jstl/functions" prefix="fn" %>
...
<input name="username" value="${fn:escapeXml(param.username)}">

C'est ça. Pas besoin de liste noire. Notez que les données contrôlées par l'utilisateur couvrent tout qui provient d'une requête HTTP: les paramètres de la requête, le corps et les en-têtes (!!).

Si vous l'échappez HTML pendant le traitement des données soumises et/ou le stockage dans la base de données, alors tout est réparti sur le code d'entreprise et/ou dans la base de données. Ce n'est qu'un problème de maintenance et vous risquez des doubles échappements ou plus lorsque vous le faites à différents endroits (par exemple & deviendrait &amp;amp; au lieu de &amp; pour que l'utilisateur final voie littéralement &amp; au lieu de & en vue. Le code métier et la base de données ne sont à leur tour pas sensibles pour XSS. Seule la vue l'est. Vous ne devriez alors y échapper que juste là en vue.

Voir également:

41
BalusC

Utilise les deux. En fait, reportez-vous à un guide comme le OWASP XSS Prevention cheat sheet , sur les cas possibles d'utilisation de l'encodage de sortie et de la validation d'entrée.

La validation d'entrée est utile lorsque vous ne pouvez pas vous fier au codage de sortie dans certains cas. Par exemple, il vaut mieux valider les entrées apparaissant dans les URL plutôt que de coder les URL elles-mêmes (Apache ne diffusera pas une URL codée en URL). Ou d'ailleurs, validez les entrées qui apparaissent dans les expressions JavaScript.

En fin de compte, une règle empirique simple vous aidera - si vous ne faites pas suffisamment confiance à l'entrée utilisateur ou si vous pensez que certaines sources peuvent entraîner des attaques XSS malgré le codage de sortie, validez-la par rapport à une liste blanche.

Jetez un œil au code source OWASP ESAPI sur la façon dont les encodeurs de sortie et les valideurs d'entrée sont écrits dans une bibliothèque de sécurité.

6
Vineet Reynolds

Ma préférence est de coder tous les caractères non alphanumériques en tant qu'entités de caractères numériques HTML. Étant donné que presque toutes les attaques, sinon toutes, nécessitent des caractères non alphunériques (comme <, ", etc.), cela devrait éliminer une grande partie des sorties dangereuses.

Le format est & # N ;, où N est la valeur numérique du caractère (vous pouvez simplement convertir le caractère en entier et concaténer avec une chaîne pour obtenir une valeur décimale). Par exemple:

 // pseudocode Java-ish 
 StringBuffer safestrbuf = new StringBuffer (string.length () * 4); 
 Foreach (char c: string.split ()) {
 if (Character.isAlphaNumeric (c)) safestrbuf.append (c); 
 else safestrbuf.append (symbole "" + (int)); 

Vous devrez également vous assurer que vous codez immédiatement avant de sortir vers le navigateur, pour éviter le double codage ou le codage HTML mais l'envoi vers un emplacement différent.

0
atk