¿La Política de seguridad de contenido solo se aplica durante el procesamiento inicial?

8

¿Se aplica el CSP solo durante el procesamiento inicial, lo que significa que no hay cobertura continua después de que se cargue el documento? Aquí hay un ejemplo de lo que estoy hablando:

Supongamos que su página, example.com , tiene algún JS que toma el parámetro url name y lo muestra en la página:

<script nonce="test123">
$(document).ready(function() {
    $("#id").html(nameParameterTakenFromURLWithoutSanitation);
});
</script>

Si alguien visita example.com?name=<script>alert('XSS');</script> , según mis pruebas, la secuencia de comandos aún se ejecutará (aparecerá la alerta) independientemente de la CSP. Solo se bloquean los scripts ilegales que existen dentro de la respuesta inicial del servidor.

Estoy usando un enfoque CSP "estricto" que usa nonces. Aquí está la política que estoy usando:

object-src 'none';
script-src 'nonce-test123' 'unsafe-inline' 'unsafe-eval' 'strict-dynamic' https: http:;
report-uri http://localhost:8080/csp-collector

¿Por qué no está bloqueado el script?

    
pregunta Andrew Schmitt 26.10.2016 - 21:13
fuente

3 respuestas

10

Introducción

El navegador debe aplicar el CSP siempre y cuando permanezca en la página, y no solo mientras se carga o renderiza originalmente. Todo lo demás lo haría bastante desdentado.

Por lo tanto, el comportamiento que está experimentando no tiene nada que ver con cuando se carga el script. En cambio, se trata de lo que lo carga. Hay dos problemas.

Problema 1: estricto-dinámico

Dejaré que Mozilla lo explique:

  

La directiva de dinámica estricta especifica que la confianza dada explícitamente a un script presente en el marcado, acompañándolo con un nonce o un hash, se propagará a todos los scripts cargados por ese script raíz.

Por lo tanto, cuando confía en un script dándole un nonce, puede a su vez cargar otros scripts. Eso significa que si tiene una vulnerabilidad DOM XSS en un script con un nonce, el CSP no lo salvará. La solución es eliminar 'strict-dynamic' (pero eso, por supuesto, será problemático si confía en esta función).

Problema 2: unsafe-eval

Para cargar el script, usa jQuery .html() . En algún lugar del código fuente de jQuery (línea 343 para ser exactos) hace una llamada a los viejos. eval() .

Así que si ejecuta el código

$(".test").html("<scr" + "ipt>alert('XSS');</scr" + "ipt>");

jQuery por alguna razón (no me preguntes por qué, he intentado y no he seguido el código fuente) ejecutará lo siguiente:

eval("alert('XSS');");

Esto significa que el CSP ya no se aplica: después de todo, no estás creando una nueva etiqueta de script, estás evaluando una cadena.

Aquí la solución es eliminar 'unsafe-eval' del CSP, pero eso rompería jQuery. La solución a eso podría ser actualizar a jQuery 3, que al inspeccionar superficialmente la fuente parece haber solucionado esto.

Conclusión

Esto significa que todo el código (usando jQuery 2) en el formulario

x.html(unsafeFromURL);

puede ser vulnerable a XSS incluso si se establece un CSP . Creo que esto es inesperado para mucha gente (fue para mí). Pero sirve como un recordatorio de otro punto importante: No debes usar CSP como tu única línea de defensa contra XSS .

También tenga en cuenta que esto no es un problema con el funcionamiento de CSP, sino con el funcionamiento de jQuery.

    
respondido por el Anders 26.10.2016 - 23:29
fuente
1

Su ejemplo comienza deshabilitando el script en línea de CSP y la protección eval, que son sus dos controles de seguridad principales; particularmente el en línea, ya que es la principal forma de prevenir XSS.

Luego, ejecuta un script que escribe una etiqueta <script> en la página, lo que hace que se coloque en la página. Si hubiera escrito manualmente la misma etiqueta de script en la página a través del código del lado del servidor, entonces habría obtenido el mismo resultado. El hecho de que lo hiciste con JavaScript es irrelevante en su mayoría aquí.

Al deshabilitar las funciones de protección de claves de CSP, eliminó toda la protección contra XSS y luego obtuvo XSS.

    
respondido por el Polynomial 26.10.2016 - 23:18
fuente
0

Para responder al título de su pregunta: No, el CSP se aplica durante toda la vida útil del documento / recurso HTML, a menos que vaya a una URL completamente diferente.

La razón por la que su script no está bloqueado debido a la presencia de strict-dynamic en los navegadores que lo admiten y en los que no lo admiten unsafe-inline hará que no se bloquee.

Veamos el caso de los navegadores que admiten strict-dynamic :

El objetivo principal de estrictamente dinámico es deshacerse de la lista blanca (que no es tan segura debido a JSONP, etc. Ver aquí ) y también para permitir la carga dinámica de scripts que se realiza mediante una gran cantidad de API en la web.

Básicamente, si está demorando dinámicamente un script mediante la creación de una etiqueta de script, se bloqueará si usa nonces. Entonces, lo que hace estrictamente dinámico es si un script que tiene un nonce y por lo tanto es confiable, se le permite cargar scripts como este (creación de etiquetas de script) dinámicamente.

Entonces, en tu caso:

<script nonce="test123">
    $(document).ready(function() {
        $("#id").html(nameParameterTakenFromURLWithoutSanitation);
    });
</script>

Crea una etiqueta de script si el parámetro de nombre es say: <script>alert('XSS');</script> , por lo que, por definición de strict-dynamic , debería ejecutarse.

La principal preocupación aquí para mí es por qué estás usando .html() ? ¿Esperas que el nombre tenga alguna marca HTML? Si no es así, utilice .text() que escapa a cualquier marca HTML y por lo tanto evita que XSS.     

respondido por el tapananand 17.11.2016 - 07:24
fuente

Lea otras preguntas en las etiquetas