Pregunta

¿Qué debo hacer para evitar XSS en Spring MVC? En este momento sólo estoy poniendo todos los lugares en los que el texto de salida de usuario en etiquetas JSTL <c:out> o funciones fn:escapeXml(), pero esto parece propenso a errores, ya que podría perder un lugar.

¿Hay una manera sistemática fácil de evitar esto? Tal vez como un filtro o algo? Estoy recogiendo de entrada mediante la especificación de parámetros @RequestParam en mis métodos de controlador.

¿Fue útil?

Solución

En la primavera se puede escapar el código HTML de las páginas JSP generadas por las etiquetas <form>. Esto cierra a un montón vías de ataques XSS, y se puede hacer de forma automática de tres maneras:

Para toda la aplicación en el archivo web.xml:

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

Para todas las formas en una página determinada en el propio archivo:

<spring:htmlEscape defaultHtmlEscape="true" /> 

Para cada forma:

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

Otros consejos

Trate XSSFilter .

utilizo Hibernate Validator través @Valid para todos los objetos de entrada (de unión y JSON @RequestBody, veo https : //dzone.com/articles/spring-31-valid-requestbody). Así @org.hibernate.validator.constraints.SafeHtml es una buena solución para mí.

Hibernate SafeHtmlValidator depende de org.jsoup, por lo que se necesita para agregar uno más dependencias del proyecto:

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

Para User frijol con el campo

@NotEmpty
@SafeHtml
protected String name;

para intento de actualización con valor <script>alert(123)</script> en el controlador

@PutMapping(value = "/{id}", consumes = MediaType.APPLICATION_JSON_VALUE)
public void update(@Valid @RequestBody User user, @PathVariable("id") int id) 

o

@PostMapping
public void createOrUpdate(@Valid User user) {

se lanza BindException por la unión y MethodArgumentNotValidException para @RequestBody con el mensaje por defecto:

name may have unsafe html content

Validador funciona tan bien para la unión, como antes persistente. Aplicaciones podrían ser probados en http://topjava.herokuapp.com/

Cuando usted está tratando de evitar XSS, es importante pensar en el contexto. A modo de ejemplo cómo y por qué de escape es muy diferente si está ouputting de datos dentro de una variable en un fragmento de código JavaScript en contraposición a la salida de datos en una etiqueta HTML o un atributo HTML.

Tengo un ejemplo de esto aquí: http://erlend.oftedal.no/blog /? blogid = 91

también comprobación la Hoja de OWASP XSS Prevención de trucos: http: //www.owasp .org / index.php / XSS_% 28Cross_Site_Scripting% 29_Prevention_Cheat_Sheet

Así que la respuesta corta es, asegúrese de escapar de salida, como lo sugiere Tendayi Mawushe, pero tener especial cuidado cuando se está dando salida de datos en atributos HTML o Javascript.

¿Cómo están recogiendo la entrada del usuario en el primer lugar? Esta pregunta / respuesta puede ayudar si usted está usando un FormController:

primavera: escapar de entrada cuando se une a la orden

Siempre comprobar manualmente los métodos, las etiquetas que utiliza, y asegurarse de que siempre se escapan (una vez) en el final. Marcos tienen muchos errores y diferencias en este aspecto.

Una visión general: http://www.gablog.eu/online/node/91

En lugar de confiar únicamente en <c:out />, una biblioteca AntiXSS debería también ser utilizado, que no sólo codificar sino también desinfectar script malicioso en la entrada. Uno de los mejores biblioteca disponible es OWASP AntiSamy , es muy flexible y se puede configurar (utilización de la política archivos XML) según el requisito.

Por ejemplo, si una aplicación sólo soportes de entrada de texto a continuación, más genérica archivo de política "nofollow" proporcionado por OWASP puede utilizarse que desinfecta y elimina la mayoría de las etiquetas hTML. Del mismo modo, si los editores de soporte de aplicaciones HTML (como tinymce) y que requieren todo tipo de etiquetas HTML, una política más flexible puede ser el uso como archivo de política de eBay

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

solución a la cuestión XSS es filtrar todos los campos de texto en la forma   en el momento de enviar el formulario.

    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 segunda clase cuyo nombre en código es RequestWrapper.java:

paquete 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;
    }
  

Lo único que permanece es la entrada XML en el archivo 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>

El / * indica que por cada petición realizada desde el navegador, se llamará     CrossScriptingFilter clase. Que analizar todos los componentes / elementos provienen de la solicitud y     reemplazará todas las etiquetas JavaScript formuladas por hackers con cadena vacía es decir

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top