He preguntado esto sobre el Desbordamiento de pila porque está relacionado con un problema de programación (cómo mitigar las vulnerabilidades en el código) pero tengo algunas preguntas más amplias y una falta de comprensión sobre cómo mitigar la vulnerabilidad. Tenga en cuenta la sección de actualización a continuación donde he implementado las mitigaciones en estas preguntas vinculadas aquí y aquí .
He ejecutado una herramienta de prueba de lápiz (Burp) contra mi aplicación de nodo / expreso / angular e identificó una vulnerabilidad XSS reflejada específicamente al intentar una solicitud GET
para activos estáticos (no se encontraron vulnerabilidades notables para ninguno de las solicitudes que se realizan cuando un usuario interactúa con la aplicación).
El detalle del problema es:
El nombre de un parámetro de URL suministrado arbitrariamente se copia en un Expresión de JavaScript que no está encapsulada en ninguna cita marcas. La carga útil 41b68 (a) 184a9 = 1 se presentó a nombre de un parámetro de URL suministrado arbitrariamente. Esta entrada se hizo eco sin modificar en la respuesta de la aplicación.
Este comportamiento demuestra que es posible inyectar JavaScript comandos en el documento devuelto. Se intentó identificar una ataque completo de prueba de concepto para inyectar JavaScript arbitrario pero Esto no tuvo éxito. Debe examinar manualmente la aplicación comportamiento e intento de identificar cualquier validación de entrada inusual u otra obstáculos que pueden estar en su lugar.
La vulnerabilidad se probó al pasar un parámetro de url arbitrario a la solicitud de esta manera:
GET /images/?41b68(a)184a9=1
La respuesta fue:
HTTP/1.1 404 Not Found
X-Content-Security-Policy: connect-src 'self'; default-src 'self'; font-src 'self'; frame-src; img-src 'self' *.google-analytics.com; media-src; object-src; script-src 'self' 'unsafe-eval' *.google-analytics.com; style-src 'self' 'unsafe-inline'
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
Strict-Transport-Security: max-age=10886400; includeSubDomains; preload
X-Download-Options: noopen
X-Content-Type-Options: nosniff
Content-Type: text/html; charset=utf-8
Content-Length: 52
Date: Wed, 08 Oct 2015 10:46:43 GMT
Connection: close
Cannot GET /images/?41b68(a)184a9=1
Puede ver que tengo CSP en su lugar (usando Casco para implementar) y otras protecciones contra las vulnerabilidades. La aplicación se sirve a través de https, pero no se requiere autenticación del usuario. CSP restringe las solicitudes del dominio de la aplicación y Google Analytics.
El informe de prueba del lápiz recomienda la entrada de validación (lo estoy, pero seguramente eso haría que las solicitudes, incluidos los datos enviados por un usuario, ¿fueran inseguras si no lo fuera?), y la codificación de html que hace el ángulo de forma predeterminada, además de las URL de solicitud GET se están realizando. escapado (ver actualización abajo).
Estoy realmente luchando para encontrar una solución para prevenir o mitigar esto para esas solicitudes de activos estáticos:
- ¿Debo incluir en la lista blanca todas las solicitudes de mi solicitud en csp?
- ¿Puedo hacer esto o solo incluiré en la lista blanca los dominios?
- ¿Pueden / deberían todas las respuestas de node / express a las solicitudes de activos estáticos estar codificadas de alguna manera (ver la actualización en url que se escapa a continuación)?
- El informe indica que "El nombre de un parámetro de URL suministrado de manera arbitraria se copia en una expresión de JavaScript que no está encapsulada entre comillas ". ¿Podría esta expresión estar en algún lugar del código expreso que maneja los activos estáticos de retorno?
- ¿O que el parámetro de solicitud GET se puede evaluar de alguna manera en el código de mi aplicación?
Actualizar
Habiendo investigado esto, parece que al menos parte de la mitigación es datos de escape en los valores de param url y desinfecte la entrada en el url .
El escape de la URL ya está en su lugar, por lo que:
curl 'http://mydomain/images/?<script>alert('hello')</script>'
devuelve
Cannot GET /images/?<script>alert(hello)</script>
También he puesto express-sanitized en su lugar encima de esto.
Sin embargo, si rizo la prueba original, el parámetro de solicitud aún se refleja.
curl 'http://mydomain/images/?41b68(a)184a9=1'
Cannot GET /images/?41b68(a)184a9=1
Lo que usted esperaría porque html no se está insertando en la url.
Todas las respuestas a las solicitudes GET para activos estáticos se manejan mediante app.use(express.static('static-dir'))
, por lo que la consulta se pasa a esto. express.static
se basa en serve-static que depende de parseurl .