Comment puis-je prévenir les attaques XSS dans une application Web JSP/Servlet?
Il est possible d’empêcher XSS dans JSP en utilisant la balise [~ # ~] jstl [~ # ~]<c:out>
ou fn:escapeXml()
fonction EL lorsque (ré) affiche une entrée contrôlée par l'utilisateur . Cela inclut les paramètres de requête, les en-têtes, les cookies, l'URL, le corps, etc. Tout ce que vous extrayez de l'objet de requête. De plus, les entrées contrôlées par l'utilisateur issues de requêtes précédentes qui sont stockées dans une base de données doivent être ignorées pendant le réaffichage.
Par exemple:
<p><c:out value="${bean.userControlledValue}"></p>
<p><input name="foo" value="${fn:escapeXml(param.foo)}"></p>
Cela échappera aux caractères susceptibles de malformer le code HTML rendu, tels que <
, >
, "
, '
Et &
En Entités HTML/XML telles que <
, >
, "
, '
Et &
.
Notez qu'il n'est pas nécessaire de leur échapper dans le code Java (Servlet), car ils sont inoffensifs là-bas. Certains peuvent choisir de les échapper lors de demande traitement (comme vous le faites dans Servlet ou Filtre) au lieu de réponse traitement (comme dans JSP), mais vous risqueriez de perdre inutilement les données dans les données (par exemple, &
devient &amp;
au lieu de &
et l'utilisateur final verrait que &
était présenté) , ou que les données stockées dans la base de données deviennent impossibles à importer (par exemple, lors de l’exportation de données au format JSON, CSV, XLS, PDF, etc., ce qui ne nécessite pas l’échappement de code HTML). Vous perdrez également le contrôle social, car vous ne savez plus ce que l'utilisateur a réellement renseigné. En tant qu'administrateur de site, vous souhaitez vraiment savoir quels utilisateurs/adresses IP essaient d'exécuter XSS afin de pouvoir facilement suivre et agissez en conséquence. Les échappées pendant le traitement des demandes ne devraient être utilisées que comme dernier recours lorsque vous avez vraiment besoin de réparer dans les plus brefs délais l'épave d'une application Web héritée mal développée. Néanmoins, vous devriez en fin de compte réécrire vos fichiers JSP pour qu'ils soient compatibles XSS.
Si vous souhaitez afficher à nouveau les entrées contrôlées par l'utilisateur au format HTML, dans lesquelles vous souhaitez autoriser uniquement un sous-ensemble spécifique de balises HTML telles que <b>
, <i>
, <u>
, Etc., vous devez ensuite assainir l’entrée par une liste blanche. Vous pouvez utiliser un analyseur HTML tel que Jsoup . Cependant, il est préférable d’introduire un langage de balisage convivial, tel que Markdown (également utilisé ici dans Stack Overflow). Ensuite, vous pouvez utiliser un analyseur syntaxique Markdown tel que CommonMark . Il a également intégré des fonctionnalités de désinfection HTML. Voir aussi Je recherche un encodeur HTML Java _ .
La seule préoccupation du côté serveur en ce qui concerne les bases de données est la prévention de injection SQL . Vous devez vous assurer de ne jamais concaténer par une chaîne une entrée contrôlée par l'utilisateur directement dans la requête SQL ou JPQL et que vous utilisez des requêtes paramétrées jusqu'au bout. En termes JDBC, cela signifie que vous devez utiliser PreparedStatement
au lieu de Statement
. En termes JPA, utilisez Query
.
Une alternative serait de migrer de JSP/Servlet vers le framework MVC de Java EE [~ # ~] jsf [~ # ~] . Il intègre la prévention XSS (et CSRF!) Partout. Voir aussi Prévention des attaques par injection CSRF, XSS et SQL dans JSF .
How-to-prevent-xss a été demandé à plusieurs reprises. Vous trouverez beaucoup d'informations dans StackOverflow. En outre, site Web OWASP a une feuille de triche de prévention XSS que vous devriez passer.
Sur les bibliothèques à utiliser, bibliothèque ESAPI de OWASP a Java. Vous devriez l'essayer. De plus, chaque framework que vous utilisez possède une certaine protection contre XSS. Encore une fois, le site Web de l'OWASP contient des informations sur les cadres les plus populaires, je vous recommande donc de consulter leur site.
J'ai eu beaucoup de chance avec OWASP Anti-Samy et un conseiller AspectJ sur tous mes contrôleurs Spring qui empêchent XSS d'entrer.
public class UserInputSanitizer {
private static Policy policy;
private static AntiSamy antiSamy;
private static AntiSamy getAntiSamy() throws PolicyException {
if (antiSamy == null) {
policy = getPolicy("evocatus-default");
antiSamy = new AntiSamy();
}
return antiSamy;
}
public static String sanitize(String input) {
CleanResults cr;
try {
cr = getAntiSamy().scan(input, policy);
} catch (Exception e) {
throw new RuntimeException(e);
}
return cr.getCleanHTML();
}
private static Policy getPolicy(String name) throws PolicyException {
Policy policy =
Policy.getInstance(Policy.class.getResourceAsStream("/META-INF/antisamy/" + name + ".xml"));
return policy;
}
}
Vous pouvez obtenir le conseiller AspectJ auprès de la cet article stackoverflow
Je pense que c est une meilleure approche que c: en particulier si vous utilisez beaucoup de javascript.
La gestion de XSS nécessite plusieurs validations, les données côté client.
Il n’existe pas de solution simple, prête à utiliser, contre XSS. L'API ESAPI OWASP prend en charge l'échappement qui est très utile, et ils ont des bibliothèques de balises.
Mon approche consistait essentiellement à étendre les balises stuts 2 de la manière suivante.
Si vous ne souhaitez pas modifier les classes à l'étape 1, une autre approche consiste à importer les balises ESAPI dans les modèles freemarker et à les quitter en cas de besoin. Ensuite, si vous devez utiliser une balise s: property dans votre JSP, enveloppez-la avec une balise ESAPI.
J'ai écrit une explication plus détaillée ici.
http://www.nutshellsoftware.org/software/securing-struts-2-using-esapi-part-1-securing-outputs/
Je conviens que s'échapper des entrées n'est pas idéal.
Je suggérerais de tester régulièrement les vulnérabilités à l'aide d'un outil automatisé et de corriger tout ce qu'il trouve. Il est beaucoup plus facile de suggérer une bibliothèque pour aider avec une vulnérabilité spécifique que pour toutes les attaques XSS en général.
Skipfish est un outil open source de Google sur lequel j'ai étudié: il trouve pas mal de fichiers et semble valoir la peine d'être utilisé.
Mon opinion personnelle est d’éviter d’utiliser les pages JSP/ASP/PHP/etc. Exportez plutôt vers une API similaire à SAX (conçue uniquement pour appeler plutôt que pour gérer). De cette façon, une seule couche doit créer une sortie bien formée.
Si vous souhaitez échapper automatiquement toutes les variables JSP sans avoir à envelopper explicitement chaque variable, vous pouvez utiliser un résolveur EL comme détaillé ici source et un exemple (JSP 2.0 ou plus récent) , et discuté plus en détail ici :
Par exemple, en utilisant le résolveur EL mentionné ci-dessus, votre code JSP restera tel quel, mais chaque variable sera automatiquement échappée par le résolveur.
...
<c:forEach items="${orders}" var="item">
<p>${item.name}</p>
<p>${item.price}</p>
<p>${item.description}</p>
</c:forEach>
...
Si vous voulez forcer l'échappement par défaut dans Spring, vous pouvez également considérer cela, mais cela n'échappera pas aux expressions EL, mais simplement à la sortie des balises, je pense:
http://forum.springsource.org/showthread.php?61418-Spring-cross-site-scripting&p=205646#post205646
Remarque: Une autre approche de l'échappement EL utilisant des transformations XSL pour le prétraitement des fichiers JSP est disponible ici:
http://therning.org/niklas/2007/09/preprocessing-jsp-files-to-automatically-escape-el-expressions/