Comment puis-je empêcher les gens de faire des XSS au printemps MVC?
Que dois-je faire pour empêcher XSS en MVC printemps? En ce moment, je ne fais que mettre tous les endroits où je sors du texte utilisateur dans les fonctions JSTL <c:out>
tags ou fn:escapeXml()
, mais cela semble sujet à erreur car je pourrais manquer un endroit.
y a-t-il un moyen facile et systématique de prévenir cela? Peut-être comme un filtre ou quelque chose? Je collecte les entrées en spécifiant les paramètres @RequestParam
sur mes méthodes de controller.
8 réponses
au printemps, vous pouvez échapper au html des pages JSP générées par les tags <form>
. Cela ferme beaucoup de possibilités pour les attaques XSS, et peut être fait automatiquement de trois façons:
pour l'ensemble de la demande dans le dossier web.xml
:
<context-param>
<param-name>defaultHtmlEscape</param-name>
<param-value>true</param-value>
</context-param>
pour tous les formulaires sur une page donnée du dossier lui-même:
<spring:htmlEscape defaultHtmlEscape="true" />
pour chaque formulaire:
<form:input path="someFormField" htmlEscape="true" />
quand vous essayez d'empêcher XSS, il est important de penser au contexte. À titre d'exemple, comment et quoi s'échapper est très différent si vous récupérez des données à l'intérieur d'une variable dans un extrait javascript par opposition à extraire des données dans une balise HTML ou un attribut HTML.
j'en ai un exemple ici: http://erlend.oftedal.no/blog/?blogid=91
consultez aussi la fiche de renseignements sur la prévention de L'OWASP XSS: http://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet
donc la réponse courte est, assurez-vous que vous échappez à la sortie comme suggéré par Tendayi Mawushe, mais faites attention quand vous êtes la sortie des données dans les attributs HTML ou javascript.
J'utilise Hibernate Validator via @Valid
pour tous les objets d'entrée (binding et @RequestBody
json, voir https://dzone.com/articles/spring-31-valid-requestbody ). Donc @org.hibernate.validator.constraints.SafeHtml
est une bonne solution pour moi.
hibernation SafeHtmlValidator
dépend de org.jsoup
, il est donc nécessaire d'ajouter une dépendance de projet supplémentaire:
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.10.1</version>
</dependency>
pour haricots User
avec champ
@NotEmpty
@SafeHtml
protected String name;
pour la tentative de mise à jour avec la valeur <script>alert(123)</script>
dans le contrôleur
@PutMapping(value = "/{id}", consumes = MediaType.APPLICATION_JSON_VALUE)
public void update(@Valid @RequestBody User user, @PathVariable("id") int id)
ou
@PostMapping
public void createOrUpdate(@Valid User user) {
est lancé BindException
pour reliure et MethodArgumentNotValidException
pour @RequestBody
avec message par défaut:
name may have unsafe html content
Validateur fonctionne aussi bien pour la liaison, comme avant persister. Les applications peuvent être testées à http://topjava.herokuapp.com /
comment collectez-vous les données de l'utilisateur? Cette question / réponse peut vous aider si vous utilisez un FormController
:
le Printemps: s'échapper d'entrée lors de la liaison de commande
vérifiez toujours manuellement les méthodes, les étiquettes que vous utilisez, et assurez-vous qu'elles s'échappent toujours (une fois) à la fin. Les cadres ont beaucoup de bugs et de différences dans cet aspect.
Un aperçu: http://www.gablog.eu/online/node/91
au lieu de se baser uniquement sur <c:out />
, une bibliothèque antixss devrait également être utilisée, qui non seulement encodera mais aussi nettoiera les scripts malveillants en entrée. Une des meilleures bibliothèques disponibles est OWASP Antisamy , il est très flexible et peut être configuré(en utilisant des fichiers de politique xml) selon les exigences.
pour par exemple si une application ne prend en charge que l'entrée de texte, alors la plus générique fichier de politique fourni par OWASP peut être utilisé qui épure et supprime la plupart des balises html. De même, si l'application prend en charge les éditeurs html(tels que tinymce) qui ont besoin de toutes sortes de balises html, une politique plus souple peut être utilisée comme fichier de politique ebay
**To avoid XSS security threat in spring application**
solution à la question XSS est de filtrer tous les champs de texte dans la forme au moment de la soumission du formulaire.
It needs XML entry in the web.xml file & two simple classes.
java code :-
The code for the first class named CrossScriptingFilter.java is :
package com.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
public class CrossScriptingFilter implements Filter {
private static Logger logger = Logger.getLogger(CrossScriptingFilter.class);
private FilterConfig filterConfig;
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
public void destroy() {
this.filterConfig = null;
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
logger.info("Inlter CrossScriptingFilter ...............");
chain.doFilter(new RequestWrapper((HttpServletRequest) request), response);
logger.info("Outlter CrossScriptingFilter ...............");
}
}
la deuxième classe de code appelée RequestWrapper.java est :
package com.filtre;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.log4j.Logger;
public final class RequestWrapper extends HttpServletRequestWrapper {
private static Logger logger = Logger.getLogger(RequestWrapper.class);
public RequestWrapper(HttpServletRequest servletRequest) {
super(servletRequest);
}
public String[] getParameterValues(String parameter) {
logger.info("InarameterValues .. parameter .......");
String[] values = super.getParameterValues(parameter);
if (values == null) {
return null;
}
int count = values.length;
String[] encodedValues = new String[count];
for (int i = 0; i < count; i++) {
encodedValues[i] = cleanXSS(values[i]);
}
return encodedValues;
}
public String getParameter(String parameter) {
logger.info("Inarameter .. parameter .......");
String value = super.getParameter(parameter);
if (value == null) {
return null;
}
logger.info("Inarameter RequestWrapper ........ value .......");
return cleanXSS(value);
}
public String getHeader(String name) {
logger.info("Ineader .. parameter .......");
String value = super.getHeader(name);
if (value == null)
return null;
logger.info("Ineader RequestWrapper ........... value ....");
return cleanXSS(value);
}
private String cleanXSS(String value) {
// You'll need to remove the spaces from the html entities below
logger.info("InnXSS RequestWrapper ..............." + value);
//value = value.replaceAll("<", "& lt;").replaceAll(">", "& gt;");
//value = value.replaceAll("\(", "& #40;").replaceAll("\)", "& #41;");
//value = value.replaceAll("'", "& #39;");
value = value.replaceAll("eval\((.*)\)", "");
value = value.replaceAll("[\\"\\'][\s]*javascript:(.*)[\\"\\']", "\"\"");
value = value.replaceAll("(?i)<script.*?>.*?<script.*?>", "");
value = value.replaceAll("(?i)<script.*?>.*?</script.*?>", "");
value = value.replaceAll("(?i)<.*?javascript:.*?>.*?</.*?>", "");
value = value.replaceAll("(?i)<.*?\s+on.*?>.*?</.*?>", "");
//value = value.replaceAll("<script>", "");
//value = value.replaceAll("</script>", "");
logger.info("OutnXSS RequestWrapper ........ value ......." + value);
return value;
}
la seule chose qui reste est L'entrée XML dans le web.fichier xml:
<filter>
<filter-name>XSS</filter-name>
<display-name>XSS</display-name>
<description></description>
<filter-class>com.filter.CrossScriptingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>XSS</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
/ * indique que pour chaque demande faite à partir du navigateur, il va appeler Classe CrossScriptingFilter. Qui analysera tous les composants / éléments provenant de la demande & va remplacer toutes les Balises javascript mises par hacker avec la chaîne vide I. e