¿El uso de HttpServletRequest.getQueryString () para un encabezado de respuesta es vulnerable a la división de respuestas?

7

Me han dicho que al utilizar HttpServletRequest.getQueryString() en un encabezado de respuesta hace que mi aplicación sea susceptible a los ataques de división de respuesta HTTP, pero no veo cómo.

Está claro en el caso de getParameter(String) , que decodifica los valores codificados en porcentaje, pero getQueryString() no lo hace. De la documentación:

  

El valor no está descodificado por el contenedor.

Fragmento de código fuente que ilustra lo que estoy haciendo:

String path = "some_url";

String qs = req.getQueryString();
if (qs != null)
    path += "?" + qs;

// response instanceof HttpServletResponse
response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
response.setHeader("Location", path);

Intenté reproducir el problema y acabo de hacer que las nuevas líneas codificadas en porcentaje se repitan en la respuesta. Cuando cambio el código a getParameter(…) , funciona como se esperaba (excepto que mi contenedor es lo suficientemente bueno como para quitar las nuevas líneas del valor del encabezado, pero en teoría al menos funciona). Esta pregunta similar sobre Desbordamiento de pila pregunta Lo mismo, y un comentario a la respuesta que señala que getQueryString() no se decodifica no obtuvo respuesta.

¿Me estoy perdiendo algo aquí? ¿O es incorrecto el consejo?

    
pregunta mwl 29.11.2015 - 22:40
fuente

1 respuesta

1

El patrón general de uso de datos que proviene del usuario sin sanearlo es una fuente de vulnerabilidades. Cosas típicas como XSS y SQLi. En este caso, usted toma la entrada del usuario y la convierte directamente en un encabezado. Esto podría llevar a la división de la respuesta, a la inyección del encabezado, y quizás a otro problema o dos (por ejemplo: CSRF puede ser posible si puede inyectar Javascript). Pero usted declara que:

  

mi contenedor es lo suficientemente bueno como para quitar las nuevas líneas del valor del encabezado

por lo que esto está evitando la explotación real.

Sospecho que incluso si filtraras la entrada, como por ejemplo:

path += "?" + sanitize(qs);

para una función sanitize apropiada (por ejemplo, desde Proyecto AntiSamy de OWASP ) que su analizador estático Sigue dándote este hallazgo. Entonces, al final, marcará este resultado como falso positivo ( Not an issue si está usando Fortify). La única pregunta es si debe incluir un cambio de código antes de marcar el resultado como un falso positivo.

Mi opinión es que si la API dice explícitamente que es responsable del manejo seguro de líneas nuevas y otros caracteres especiales, entonces no es necesario que realice ninguna acción. Cuando miro el Javadoc para HttpServletResponse.setHeader , no veo ninguna mención de cómo se manejarán los caracteres especiales. Por lo tanto, a menos que la especificación indique explícitamente un manejo seguro de esto (no creo que lo haga, pero no busqué esto en la especificación Servlet), recomendaría desinfectar la entrada y volver a ejecutar el escáner estático. Si, como espero, continúa informando este problema, márquelo como falso positivo y tenga la seguridad de que todo está bien.

La razón por la que creo que solo debe confiar en este comportamiento si está especificado en la especificación es que ese es el único comportamiento que está garantizado. Una nueva versión de su contenedor Servlet u otro contenedor en conjunto podría cambiar este comportamiento. Es muy poco probable que detecte un cambio de este tipo, aunque podría hacer que su sitio sea vulnerable.

    
respondido por el Neil Smithline 30.11.2015 - 01:01
fuente

Lea otras preguntas en las etiquetas