2010-12-16 33 views
8

Estoy trabajando en la prevención de cross site scripting (XSS) en una aplicación web basada en Java, Spring. Ya he implementado un filtro de servlet similar a este ejemplo http://greatwebguy.com/programming/java/simple-cross-site-scripting-xss-servlet-filter/ que desinfecta toda la entrada en la aplicación. Como medida de seguridad adicional, me gustaría también desinfectar todo el resultado de la aplicación en todos los JSP. Hice algunas investigaciones para ver cómo se podía hacer esto y encontré dos opciones complementarias.Alternativa al uso de c: out para evitar XSS

Uno de ellos es el uso del atributo defaultHtmlEscape de Spring. Esto fue muy fácil de implementar (unas pocas líneas en web.xml), y funciona muy bien cuando su salida está pasando por una de las etiquetas de primavera (es decir, mensaje o etiquetas de formulario). La otra opción que he encontrado es no usar directamente expresiones EL como ${...} y usar <c:out value="${...}" />

Ese segundo enfoque funciona perfectamente, sin embargo, debido al tamaño de la aplicación en la que estoy trabajando (más de 200 archivos JSP). Es una tarea muy engorrosa tener que reemplazar todos los usos inapropiados de expresiones EL con la etiqueta c:out. También se convertiría en una tarea engorrosa en el futuro asegurarse de que todos los desarrolladores cumplan con esta convención de usar la etiqueta c:out (sin mencionar cuánto más ilegible sería el código).

¿Hay alguna forma alternativa de evitar la salida de expresiones EL que requerirían menos modificaciones de código?

Respuesta

10

Desde Servlet 2.5/JSP 2.1 puede crear un ELResolver personalizado que hace eso. Puede registrarlo en ServletContextListener#contextInitialized().

@Override 
public void contextInitialized(ServletContextEvent event) { 
    JspFactory.getDefaultFactory() 
     .getJspApplicationContext(event.getServletContext()) 
     .addELResolver(new YourCustomELResolver()); 
} 

En el ELResolver#getValue() que podría hacer el trabajo de escapar.

Su único problema es que no podrá mostrar HTML allí donde está permitido (es decir, desinfectarse de etiquetas/atributos maliciosos por medio de una lista blanca para que termine con etiquetas inocentes como Jsoup can do).


Dicho esto, no estoy de acuerdo en la necesidad de escapar XSS durante entrada por el Filter como usted ha mencionado en el párrafo primero de la cuestión. Te arriesgas a escapar dos veces. Solo necesita escapar exactamente en ese punto donde posiblemente pueda dañar, es decir, directamente en el lado de la vista, donde se insertará entre HTML, la salida . Recomiendo deshacerse del llamado filtro XSS y concentrarme en arreglarlo en el lado de la vista usando JSTL <c:out> o fn:escapeXml() (o un solucionador EL personalizado, pero definitivamente ese no es el enfoque normal). Los futuros mantenedores de código estarán muy agradecidos.

+1

No utilice 'fn: escapeXml' para escapar de HTML.Generará ''', que no es una entidad HTML estándar. –

+1

@Roland: no, no es así. Genera ''' que es válido tanto en HTML como en XML (al igual que 'c: out'). – BalusC

+0

Ah, eso es genial. Así que debo haber confundido con alguna otra función 'escapeXml'. Para estar seguro, lo busqué en la especificación JSTL, donde esto se menciona explícitamente. –

1

This blog post describe un ELResolver personalizado que escapa a los valores de expresión EL de tipo String. El registro de este ELResolver personalizado hará que escape la salida de todas las expresiones EL. En los casos excepcionales en los que una JSP debe programación HTML de salida, se necesita un mecanismo que no implica una expresión EL, tal como una etiqueta personalizada o un scriptlet:

<%= "Java expression hopefully returning safe HTML" %> 
Cuestiones relacionadas