Question

Que dois-je faire pour éviter XSS dans Spring MVC? En ce moment je suis en train de mettre tous les lieux où le texte de l'utilisateur de sortie I en balises JSTL de <c:out> ou des fonctions de fn:escapeXml(), mais cela semble sujette aux erreurs que je pourrais manquer un endroit.

Y at-il un moyen facile systématique pour empêcher cela? Peut-être comme un filtre ou quelque chose? Je collectionne l'entrée en spécifiant des paramètres de @RequestParam sur mes méthodes de contrôleur.

Était-ce utile?

La solution

Au printemps vous pouvez échapper à la html des pages JSP générées par les balises <form>. Cette ferme a des pistes de lot pour les attaques XSS, et peut être fait automatiquement de trois façons:

Pour l'ensemble de l'application dans le fichier web.xml:

<context-param>
    <param-name>defaultHtmlEscape</param-name>
    <param-value>true</param-value>
</context-param>

Pour toutes les formes sur une page donnée dans le fichier lui-même:

<spring:htmlEscape defaultHtmlEscape="true" /> 

Pour chaque forme:

<form:input path="someFormField" htmlEscape="true" /> 

Autres conseils

J'utilise Hibernate Validator via @Valid pour tous les objets d'entrée (liaison et @RequestBody json, voir https : //dzone.com/articles/spring-31-valid-requestbody). Alors @org.hibernate.validator.constraints.SafeHtml est une bonne solution pour moi.

Mise en veille prolongée SafeHtmlValidator dépend org.jsoup, il est donc nécessaire d'ajouter une plus dépendances du projet:

<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.10.1</version>
</dependency>

Pour User de haricot avec le champ

@NotEmpty
@SafeHtml
protected String name;

pour la mise à jour avec la valeur tentative <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 jeté BindException pour la liaison et MethodArgumentNotValidException pour @RequestBody avec le message par défaut:

name may have unsafe html content

Validator fonctionne aussi bien pour la liaison, comme avant persistant. Apps pourraient être testés à http://topjava.herokuapp.com/

Lorsque vous essayez d'éviter XSS, il est important de penser au contexte. À titre d'exemple comment et quoi échapper est très différent si vous les données ouputting à l'intérieur d'une variable dans un extrait de code JavaScript par opposition à la sortie de données dans une balise HTML ou un attribut HTML.

J'ai un exemple ici: http://erlend.oftedal.no/blog /? blogid = 91

Voir aussi la fiche OWASP XSS Prévention Cheat: http: //www.owasp .org / index.php / XSS_% 28Cross_Site_Scripting% 29_Prevention_Cheat_Sheet

Donc, la réponse courte est, assurez-vous échapper à la sortie comme suggéré par Tendayi Mawushe, mais prendre des précautions particulières lorsque vous produisez des données dans les attributs HTML ou javascript.

Comment vous percevez l'entrée d'utilisateur en premier lieu? Cette question / réponse peut aider si vous utilisez un FormController:

Spring: échapper à l'entrée lors de la liaison à commander

Toujours vérifier manuellement les méthodes, les balises que vous utilisez, et assurez-vous qu'ils échappent toujours (une fois) à la fin. Les cadres ont de nombreux bugs et les différences dans cet aspect.

Une vue d'ensemble: http://www.gablog.eu/online/node/91

Au lieu de compter uniquement sur <c:out />, une bibliothèque AntiXSS doit également être utilisé, ce qui codera non seulement, mais aussi désinfectez script malveillant en entrée. L'une des meilleures bibliothèque disponible est OWASP Antisamy , il est très flexible et peut être configuré (à l'aide des fichiers de stratégie xml) selon l'exigence.

Par exemple, si une application ne supporte que la saisie de texte alors plus générique fichier de stratégie fournie par OWASP peut être utilisé qui assainit et élimine la plupart des balises HTML. De même, si le support des applications éditeurs HTML (comme tinymce) qui ont besoin de toutes sortes de balises HTML, une politique plus souple peut être utilisé comme fichier de stratégie eBay

**To avoid XSS security threat in spring application**
  

solution au problème XSS est de filtrer tous les champs de texte sous 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 ...............");
            }

        }

Le code deuxième classe nommée RequestWrapper.java est:

paquet

com.filter;

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 est restée l'entrée XML dans le fichier web.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 appellera     CrossScriptingFilter classe. Ce qui analysera tous les composants / éléments venus de la demande et     remplacera toutes les balises javascript posées par pirate avec chaîne vide i.e.

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