Prevención de XSS en la aplicación web JSP/Servlet

10 minutos de lectura

Prevencion de XSS en la aplicacion web JSPServlet
novato

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

  • La excelente publicación sobre cómo prevenir los ataques XSS en diferentes situaciones se publica allí: stackoverflow.com/questions/19824338/…

    – usuario1459144

    13 de noviembre de 2013 a las 0:49

Prevencion de XSS en la aplicacion web JSPServlet
BalusC

XSS se puede prevenir en JSP usando JSTL <c:out> etiquetar o fn:escapeXml() Función EL al (re)mostrar entrada controlada por el usuario. Esto incluye parámetros de solicitud, encabezados, cookies, URL, cuerpo, etc. Todo lo 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 revisualización.

Por ejemplo:

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

Esto escapará los caracteres que pueden deformar el HTML renderizado, como <, >, ", ' y & dentro entidades HTML/XML tal como &lt;, &gt;, &quot;, &apos; y &amp;.

Tenga en cuenta que no necesita escapar de ellos en el código Java (Servlet), ya que son inofensivos allí. Algunos pueden optar por escapar de ellos durante solicitud procesamiento (como lo hace en Servlet o Filter) en lugar de respuesta procesamiento (como lo hace en JSP), pero de esta manera puede correr el riesgo de que los datos se doblen innecesariamente (por ejemplo, & se convierte &amp;amp; en lugar de &amp; y finalmente el usuario final vería &amp; que se está presentando), o que los datos almacenados en la base de datos se vuelven inportables (por ejemplo, al exportar datos a JSON, CSV, XLS, PDF, etc., que no requieren escape de HTML en absoluto). También perderá el control social porque ya no sabe lo que el usuario realmente completó. Como administrador del sitio, le gustaría saber qué usuarios/IP están tratando de realizar XSS, para que pueda rastrear fácilmente ellos y tomar las medidas correspondientes. Escapar durante el procesamiento de solicitudes solo debe usarse como último recurso cuando realmente necesita arreglar un choque de trenes de una aplicación web heredada mal desarrollada en el menor tiempo posible. Aún así, en última instancia, debe volver a escribir sus archivos JSP para que sean seguros para XSS.

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

La única preocupación en el lado del servidor con respecto a las bases de datos es inyección SQL prevención. Debe asegurarse de que nunca concatene cadenas de entrada controladas por el usuario directamente en la consulta SQL o JPQL y que esté utilizando consultas parametrizadas en todo momento. En términos de JDBC, esto significa que debe usar PreparedStatement en lugar de Statement. En términos de JPA, use Query.


Una alternativa sería migrar de JSP/Servlet al framework JSF de MVC de Java EE. Tiene prevención XSS (¡y CSRF!) incorporada en todo lugar. Consulte también Prevención de ataques CSRF, XSS y SQL Injection en JSF.

  • El hecho de que esté utilizando Hibernate no significa que esté a salvo de la inyección SQL. Ver blog.harpoontech.com/2008/10/… por ejemplo.

    – Tyler

    16 de septiembre de 2011 a las 23:07

  • @chad: eso no es cierto. Es solo el caso cuando está concatenando cadenas de entrada controlada por el usuario directamente en la consulta SQL/HQL/JPQL así "SELECT ... WHERE SOMEVAL = " + someval en lugar de usar consultas parametrizadas como ha mostrado. Ningún ORM puede protegerse contra este tipo de errores del desarrollador.

    – BalusC

    10 de febrero de 2012 a las 21:33


  • Creo que TIENES que validar en el servidor también. Toda la validación se puede omitir modificando los parámetros HTTP. Y a veces, los datos que persisten pueden ser consumidos por otras aplicaciones en una aplicación empresarial. A veces, no tiene acceso a las vistas de las otras aplicaciones, por lo que debe desinfectar la entrada antes de persistir en la base de datos.

    –Guido Celada

    9 oct 2014 a las 14:38

  • @Guido: no estás entendiendo el problema.

    – BalusC

    9 oct 2014 a las 15:10

  • @peater: Sí, al colocar datos no confiables dentro del código JS, debe codificar JS en lugar de codificar HTML. Y, al colocar datos que no son de confianza dentro del código CSS, debe codificar con CSS en lugar de codificar con HTML. Y, al colocar datos que no son de confianza dentro de las URL, debe codificar URL en lugar de codificar HTML. La codificación HTML solo debe usarse para colocar datos no confiables dentro del código HTML.

    – BalusC

    6 jun 2019 a las 15:00


El cómo-prevenir-xss se ha preguntado varias veces. Encontrará mucha información en StackOverflow. También, El sitio web de OWASP tiene una hoja de trucos para la prevención de XSS que debes atravesar.

En las bibliotecas a usar, Biblioteca ESAPI de OWASP tiene un sabor a java. Deberías probar eso. Además de eso, cada marco que usa tiene alguna protección contra XSS. Una vez más, el sitio web de OWASP tiene información sobre los marcos de trabajo más populares, por lo que recomendaría visitar su sitio.

1646963715 994 Prevencion de XSS en la aplicacion web JSPServlet
adam caballero

Tuve mucha suerte con OWASP Anti-Samy y un asesor de AspectJ en todos mis Spring Controllers que bloquea el ingreso 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 de esta publicación de stackoverflow

Creo que este es un mejor enfoque que c: en particular si haces mucho javascript.

  • La práctica normal es escapar de HTML de cualquier dato controlado por el usuario durante la revisualización, no durante el procesamiento de los datos enviados en el servlet ni durante el almacenamiento en la base de datos. Si lo escapa de HTML durante el procesamiento de los datos enviados y/o el almacenamiento en la base de datos, entonces todo se distribuye en el código comercial y/o en la base de datos. Eso es solo un problema de mantenimiento y correrá el riesgo de escapes dobles o más cuando lo haga en diferentes lugares. El código comercial y la base de datos, a su vez, no son sensibles para XSS. Solo la vista lo es. A continuación, debe escapar sólo justo allí a la vista.

    – Shubham Maheshwari

    29 de agosto de 2015 a las 13:28

  • Si y no. Aunque la práctica general es escapar en exhibición, hay muchas razones por las que es posible que desee desinfectar al escribir. Hay algunos casos en los que desea que sus usuarios ingresen un subconjunto de HTML y, aunque podría desinfectar la pantalla, en realidad es bastante lento e incluso confuso para los usuarios. En segundo lugar, si comparte los datos con servicios de terceros, como API externas, esos servicios pueden o no realizar la desinfección adecuada por sí mismos.

    – Adam Gent

    30 de agosto de 2015 a las 12:14

  • como usted y yo mencionamos, la “práctica normal” es escapar en exhibición. Lo que ha mencionado en su comentario anterior son casos de uso más específicos y, por lo tanto, requerirían soluciones específicas.

    – Shubham Maheshwari

    30 de septiembre de 2015 a las 18:06


  • Sí, tal vez debería aclarar mi caso de uso. Trabajo principalmente en cosas de administración de contenido (edición de HTML).

    – Adam Gent

    30 de septiembre de 2015 a las 18:14

1646963715 21 Prevencion de XSS en la aplicacion web JSPServlet
Maestro V

Administrar XSS requiere múltiples validaciones, 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 Marco de validación de entrada ESAPI. Aunque no lo he probado yo mismo (todavía), hay una anotación que verifica si hay html seguro (@SafeHtml). De hecho, podría usar el validador Hibernate con Spring MVC para validaciones de beans -> Árbitro
  2. Escape de solicitudes de URL – Para todas sus solicitudes HTTP, use algún tipo de filtro XSS. He usado 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. Escapar datos/html devuelto al cliente (mira arriba en la explicación de @BalusC).

Sugeriría probar regularmente las vulnerabilidades usando una herramienta automatizada y arreglar 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.

saltamontes es una herramienta de código abierto de Google que he estado investigando: encuentra muchas cosas y parece valer la pena usarla.

  • La prevención es mejor que el diagnóstico (por ejemplo, skipfish) seguido de soluciones rápidas posteriores.

    –Sripathi Krishnan

    17 de abril de 2010 a las 17:24

  • Estoy en desacuerdo. La prevención sin diagnóstico es solo dogma. Ejecute el diagnóstico como parte de su ciclo de CI para evitar el problema de “solución rápida”.

    – Sean Reilly

    17 de abril de 2010 a las 19:04

1646963716 17 Prevencion de XSS en la aplicacion web JSPServlet
brett.carr

No existe una solución fácil y lista para usar contra XSS. La API OWASP ESAPI tiene cierto soporte para el escape que es muy útil, y tienen bibliotecas de etiquetas.

Mi enfoque fue básicamente extender las etiquetas stuts 2 de las siguientes maneras.

  1. Modifique la etiqueta s:property para que pueda tomar atributos adicionales que indiquen qué tipo de escape se requiere (escapeHtmlAttribute=”true”, etc.). Esto implica la creación de nuevas clases Property y PropertyTag. La clase Property usa la API OWASP ESAPI para el escape.
  2. Cambie las plantillas de marcador libre para usar la nueva versión de s:property y configure el escape.

Si no desea modificar las clases en el paso 1, otro enfoque sería importar las etiquetas ESAPI en las plantillas de marcador libre y escapar según sea necesario. Luego, si necesita usar as: etiqueta de propiedad en su JSP, envuélvalo con una etiqueta ESAPI.

He escrito una explicación más detallada aquí.

http://www.nutshellsoftware.org/software/secure-struts-2-using-esapi-part-1-secure-outputs/

Estoy de acuerdo en que escapar de las entradas no es lo ideal.

  • La prevención es mejor que el diagnóstico (por ejemplo, skipfish) seguido de soluciones rápidas posteriores.

    –Sripathi Krishnan

    17 de abril de 2010 a las 17:24

  • Estoy en desacuerdo. La prevención sin diagnóstico es solo dogma. Ejecute el diagnóstico como parte de su ciclo de CI para evitar el problema de “solución rápida”.

    – Sean Reilly

    17 de abril de 2010 a las 19:04

Prevencion de XSS en la aplicacion web JSPServlet
Tom Hawtin – línea de ataque

Mi opinión personal es que deberías evitar usar páginas JSP/ASP/PHP/etc. En su lugar, envíe una salida a una API similar a SAX (solo diseñada para llamar en lugar de manejar). De esa manera, hay una sola capa que tiene que crear una salida bien formada.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad