Prevención XSS en aplicaciones web JSP/Servlet

Resuelto newbie asked hace 14 años • 10 respuestas

¿Cómo puedo prevenir ataques XSS en una aplicación web JSP/Servlet?

newbie avatar Apr 17 '10 22:04 newbie
Aceptado

XSS se puede evitar en JSP mediante el uso de la etiqueta JSTL <c:out> o fn:escapeXml()la función EL al (re)mostrar la entrada controlada por el usuario . Esto incluye parámetros de solicitud, encabezados, cookies, URL, cuerpo, etc. Cualquier cosa que extraiga del objeto de solicitud. Además, la entrada controlada por el usuario de solicitudes anteriores que se almacena en una base de datos debe escaparse durante la nueva visualización.

Por ejemplo:

<p><c:out value="${bean.userControlledValue}"></p>
<p><input name="foo" value="${fn:escapeXml(param.foo)}"></p>

Esto escapará de los caracteres que pueden tener un formato incorrecto en el HTML renderizado , como <, >, y en entidades HTML/XML como , , y ."'&&lt;&gt;&quot;&apos;&amp;

Tenga en cuenta que no necesita escapar de ellos en el código Java (Servlet), ya que allí son inofensivos. Algunos pueden optar por escapar de ellos durante el procesamiento de solicitudes (como lo hace en Servlet o Filter) en lugar del procesamiento de respuestas (como lo hace en JSP), pero de esta manera puede correr el riesgo de que los datos se escapen innecesariamente (por ejemplo, &se convierten &amp;amp;en lugar de &amp;y en última instancia, el usuario final vería &amp;lo que se presenta), o que los datos almacenados en la base de datos no se pueden transportar (por ejemplo, al exportar datos a JSON, CSV, XLS, PDF, etc., lo que no requiere ningún escape HTML). También perderá el control social porque ya no sabe lo que el usuario realmente ha completado. Como administrador del sitio, realmente le gustaría saber qué usuarios/IP están intentando realizar XSS, para poder rastrear fácilmente ellos y tomar medidas en consecuencia. Escapar durante el procesamiento de solicitudes solo debe usarse como último recurso cuando realmente necesita arreglar un desastre de una aplicación web heredada mal desarrollada en el menor tiempo posible. Aun así, en última instancia deberías reescribir tus archivos JSP para que sean seguros para XSS.

Si desea volver a mostrar la entrada controlada por el usuario como HTML y desea permitir solo un subconjunto específico de etiquetas HTML como <b>,, etc., <i>entonces <u>necesita desinfectar la entrada mediante una lista blanca. Puedes usar un analizador HTML como Jsoup para esto. Pero mucho mejor es introducir un lenguaje de marcado amigable para los humanos como Markdown (también usado aquí en Stack Overflow). Luego puedes usar un analizador de Markdown como CommonMark para esto. También tiene capacidades integradas de desinfección de HTML. Véase también Markdown o HTML .

Tenga en cuenta que el término "desinfectar", como Jsoup/Markdown/Owasp, se refiere a algo muy diferente al término "escapar", como lo <c:out>hace. Los desinfectantes de HTML básicamente limpian una cadena que contiene HTML posiblemente malicioso para que pueda usarse como HTML seguro sin necesidad de escapar. Es decir , cuando realmente pretende interpretar la entrada controlada por el usuario literalmente como HTML, incluidas etiquetas como <div>,,, etc. Los escapes de HTML básicamente impiden que se interpreten, de modo que se muestran como texto sin formato. En otras palabras, no es necesario desinfectar de antemano ningún HTML del que ya se escapará.<p><img>

La única preocupación en el lado del servidor con respecto a las bases de datos es la prevención de la inyección SQL . Debe asegurarse de no concatenar nunca la entrada controlada por el usuario directamente en la consulta SQL o JPQL y de utilizar consultas parametrizadas en todo momento. En términos de JDBC, esto significa que debes usar PreparedStatementen lugar de Statement. En términos JPA, utilice Query.


Una alternativa sería migrar de JSP/Servlet al marco MVC JSF de Java EE . Tiene prevención XSS (¡y CSRF!) incorporada en todas partes para que no tengas que manipular manualmente a tus <c:out>amigos. Consulte también Prevención de ataques de inyección CSRF, XSS y SQL en JSF .

BalusC avatar Apr 17 '2010 15:04 BalusC

Se ha preguntado varias veces sobre cómo prevenir el xss. Encontrarás mucha información en StackOverflow. Además, el sitio web de OWASP tiene una hoja de trucos para la prevención de XSS que debes consultar.

En cuanto a las bibliotecas a utilizar, la biblioteca ESAPI de OWASP tiene un sabor java. Deberías probar eso. Además de eso, cada marco que utilice tiene cierta protección contra XSS. Nuevamente, el sitio web de OWASP tiene información sobre los frameworks más populares, por lo que recomendaría visitar su sitio.

Sripathi Krishnan avatar Apr 17 '2010 15:04 Sripathi Krishnan

Tuve mucha suerte con OWASP Anti-Samy y un asesor de AspectJ en todos mis controladores Spring que bloquea la entrada de XSS.

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

}

Puede obtener el asesor de AspectJ en esta publicación de stackoverflow

Creo que este es un mejor enfoque que c:out, en particular si utilizas mucho javascript.

Adam Gent avatar Jan 31 '2011 04:01 Adam Gent

La gestión de XSS requiere múltiples validaciones y datos del lado del cliente.

  1. Validaciones de entrada (validación de formulario) en el lado del Servidor. Hay múltiples formas de hacerlo. Puede probar la validación del bean JSR 303 ( validador de hibernación ) o el marco de validación de entrada ESAPI . Aunque no lo he probado (todavía), hay una anotación que busca html seguro (@SafeHtml) . De hecho, podría usar el validador de Hibernate con Spring MVC para validaciones de beans -> Ref
  2. Escapar de solicitudes de URL : para todas sus solicitudes HTTP, utilice algún tipo de filtro XSS. He utilizado lo siguiente para nuestra aplicación web y se encarga de limpiar la solicitud de URL HTTP: http://www.servletsuite.com/servlets/xssflt.htm
  3. Los datos de escape/html se devuelven al cliente (consulte la explicación de @BalusC más arriba).
MasterV avatar Oct 30 '2012 00:10 MasterV

Sugeriría probar periódicamente las vulnerabilidades utilizando una herramienta automatizada y corregir lo que encuentre. Es mucho más fácil sugerir una biblioteca para ayudar con una vulnerabilidad específica que para todos los ataques XSS en general.

Skipfish es una herramienta de código abierto de Google que he estado investigando: encuentra bastantes cosas y parece que vale la pena usarla.

Sean Reilly avatar Apr 17 '2010 16:04 Sean Reilly