¿Cómo puedo asegurarme de que mis archivos JavaScript entregados a través de una CDN no se modifiquen?

88

Estoy trabajando en un escenario en el que algunos archivos JavaScript se alojarán en una CDN. Quiero tener algún mecanismo para que cuando estos archivos se descarguen en el lado del usuario, pueda asegurarme de que los archivos no hayan sido manipulados y que de hecho provengan del CDN especificado.

Entiendo que la tarea es muy fácil si estoy usando SSL, pero aún así, quiero asegurarme de que se sirvan los archivos correctos incluso en HTTP sin SSL.

Por lo que pude buscar, no existe ningún mecanismo como la firma digital para archivos JavaScript que sea compatible con todas las plataformas. ¿Quizás no sea necesario?

¿Existe algún método integrado en los navegadores para verificar el autor de los archivos JavaScript? ¿Hay algo que pueda hacer para hacer esto de forma segura?

baba26
fuente
13
Si bien encuentro interesante esta pregunta, ¿no está fuera de tema?
evolutionxbox
20
¿Por qué servirías archivos en http?
njzk2
12
"¿Pero por qué no existe tal mecanismo?" Porque es muy difícil . Una vez que sus datos hayan salido de su servidor, estará listo. HTTPS ayuda, pero si se trata de una conexión HTTP simple, cualquier validación puede fallar (o mejor dicho, pasar). Un ataque MITM puede simplemente modificar su firma esperada y / o la firma de lo que se le proporciona antes de que el navegador se dé cuenta de las expectativas. Entonces, cuando el usuario recibe alguna carga útil, se considerará completamente seguro ... cuando no es necesariamente eso.
VLAZ
4
"¿Pero por qué no existe tal mecanismo?" Porque ya existe una solución barata, eficaz y de amplia aplicación en HTTPS.
Kevin Krumwiede
9
Esto probablemente debería estar en ServerFault o Security, ya que en realidad se trata de servir archivos de una manera segura, y cualquier relación con la programación es solo tangencial en la medida en que dichos archivos representan el código fuente.
underscore_d

Respuestas:

140

De hecho, una característica como esta se está redactando actualmente bajo el nombre de Integridad de sub-recursos . Mire el integrityatributo de la <script>etiqueta. Si bien aún no se ha adoptado completamente en todos los ámbitos , cumple precisamente este propósito.

integrity

Contiene metadatos en línea que un agente de usuario puede usar para verificar que un recurso obtenido se haya entregado sin manipulaciones inesperadas. Consulte Integridad de subrecursos.

Fuente

La integridad de los recursos secundarios (SRI) es una característica de seguridad que permite a los navegadores verificar que los archivos que obtienen (por ejemplo, de una CDN) se entregan sin manipulación inesperada. Funciona permitiéndole proporcionar un hash criptográfico que debe coincidir con un archivo obtenido.

Fuente


Ejemplo:

<script src="https://example.com/example-framework.js"
    integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
    crossorigin="anonymous"></script>

Sin embargo, tenga en cuenta que esto no lo protegerá contra los ataques Man in the Middle si está transfiriendo sus recursos a través de HTTP simple. En este caso, el atacante puede falsificar el código hash, haciendo inútil la defensa contra archivos de script manipulados.

Por esta razón, siempre debe utilizar conexiones HTTPS seguras en lugar de HTTP simple además de las medidas de seguridad descritas anteriormente.

Timo
fuente
9
Creo que vale la pena mencionar que la verificación de integridad se puede falsificar fácilmente asumiendo que OP planea enviar su HTML en HTTP, así como sus archivos de activos. Si su sitio es HTTPS y quieren servir activos a través de HTTP, a la mayoría de los navegadores no les gustará esto e ignorarán en silencio los activos HTTP.
MonkeyZeus
3
@MonkeyZeus Esto solo sería cierto en caso de un ataque MITM o si nuestro propio servidor está comprometido, ¿correcto? Tengo entendido que la pregunta pregunta explícitamente cómo defenderse de una CDN comprometida.
Timo
10
@TimoSta ¡Exactamente! Sin estas comprobaciones, si incluye un script de, por ejemplo, https://code.jquery.com/cualquier persona que se comprometa code.jquery.compuede usar XSS en su sitio, independientemente de si code.jquery.comse accede o no a través de HTTPS. Con estas comprobaciones, el atacante solo puede evitar que se carguen los scripts, no reemplazarlos por otros maliciosos.
Ajedi32
1
@MonkeyZeus Agregué una nota a mi respuesta, expresando sus preocupaciones. ¿Estás de acuerdo con la redacción?
Timo
1
@TimoSta Muy lindo, ¡me gusta! por cierto, hice +1 incluso antes de publicar mi primer comentario :-)
MonkeyZeus
36

Busca comprobaciones de integridad de los subrecursos .

Por ejemplo, aquí está el fragmento de CDN de jQuery:

<script src="https://code.jquery.com/jquery-3.1.0.js"
        integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="
        crossorigin="anonymous"></script>
Brian
fuente
2
Totalmente inútil porque un atacante puede modificar el campo de integridad al mismo tiempo que modifica el script que estás descargando.
Lightness Races in Orbit
15
@LightnessRacesinOrbit: No si controlas tu propio dominio al que se accede a través de HTTPS pero no lo controlas code.jquery.com. Esto puede protegerlo de un compromiso code.jquery.com.
SilverlightFox
2
@SilverlightFox: Bueno, totalmente inútil contra los ataques MITM *
Lightness Races in Orbit
@LightnessRacesinOrbit Sí. Sigue siendo muy útil y habría evitado este ataque, por ejemplo: bleepingcomputer.com/news/security/…
Adrian Mouat
6

Descargo de responsabilidad: como siempre, solo debe considerar que estos mecanismos son útiles cuando use https, ya que se pueden desactivar fácilmente a través de MitM con http

Además del mecanismo de las respuestas anteriores, también puede utilizar los encabezados de respuesta http de la política de seguridad de contenido en la página principal.

http://www.html5rocks.com/en/tutorials/security/content-security-policy/

Política de seguridad de contenido: script-src 'sha256-qznLcsROx4GACP2dm0UCKCzCG-HiZ1guq6ZZDob_Tng ='

Hay algunas cosas a tener en cuenta aquí. El prefijo sha * - especifica el algoritmo utilizado para generar el hash. En el ejemplo anterior, se usa sha256-. CSP también es compatible con sha384- y sha512-. Al generar el hash no incluya las etiquetas. También son importantes las mayúsculas y los espacios en blanco, incluidos los espacios en blanco iniciales o finales.

Con Chrome 40 o posterior, puede abrir DevTools y luego volver a cargar su página. La pestaña Consola contendrá mensajes de error con el hash sha256 correcto para cada uno de sus scripts en línea.

Este mecanismo ha existido durante bastante tiempo, por lo que es probable que el soporte del navegador sea bastante bueno, solo asegúrese de verificarlo.

Además, si desea asegurarse de que los navegadores antiguos que no cumplen con las normas no sean inseguros, puede incluir una secuencia de comandos de redireccionamiento síncrono en la parte superior de la página que no esté permitida por la política.

Fabio Beltramini
fuente
ha existido durante bastante tiempo, pero la compatibilidad con el navegador no es muy buena. caniuse.com/subresource-integrity
Sp0T
@ Sp0t: la integridad de los recursos secundarios (de lo que se trata su enlace) es el mecanismo en las otras respuestas. Mi respuesta es sobre la política de seguridad del contenido, que tiene un soporte mucho mejor
Fabio Beltramini
3

Hay un punto importante sobre lo que este tipo de fichajes puede y no puede hacer. Se puede proteger al usuario de los ataques hipotéticos en los que alguien modifica su código. No puede asegurar a su sitio que su código es el código que se está ejecutando. En otras palabras, todavía no puede confiar en nada que llegue a su sitio desde el cliente.

ddyer
fuente
2

Si su modelo de adversario permite que un atacante modifique archivos JavaScript a medida que se envían desde una CDN, entonces su modelo de adversario permite que un atacante modifique la fuente de referencia a medida que se envía para eliminar cualquier intento de verificación, para alterar la dirección de origen a otra el CDN y / o eliminar la referencia al JavaScript por completo.

Y no abramos la lata de gusanos de cómo su aplicación puede determinar si el resolutor del usuario está o no resolviendo correctamente la CDN a través de solicitudes HTTP (o cualquier otro mecanismo que no tenga una cadena de confianza verificada).

/ etc / hosts:

#  ...
1.2.3.4    vile-pirates.org    trustworthy.cdn
#  ...
Eric Towers
fuente
2
La primera oración es claramente falsa. ¿Qué sucede si la página de referencia se carga a través de HTTPS y el archivo JavaScript se carga a través de HTTP-not-S?
user253751
¿O qué pasa si la propia CDN está comprometida, pero no su propio servidor?
Ajedi32
@immibis: Elijo asumir que OP no es tan irracional como para proponer tal escenario.
Eric Towers
1
@immibis ¿No es por eso que los navegadores generalmente no permiten que las páginas HTTPS carguen JS a través de HTTP?
Barmar
1
@immibis Decía que mejora una situación que ni siquiera es posible, porque los navegadores no la permiten.
Barmar
1

Puede garantizar esto con la integridad de los subrecursos. Muchas CDN públicas incluyen hashes SRI en el código integrable que se ofrece en los sitios web de CDN. Por ejemplo, en PageCDN, cuando hace clic en el archivo jquery en la página de jQuery CDN , tiene la opción de copiar la URL o usar la etiqueta de script que contiene el hash SRI como se muestra a continuación:

<script src="https://pagecdn.io/lib/jquery/3.4.1/jquery.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>

Al cargar la página, el navegador emitirá una solicitud para este recurso y, al completar la solicitud, hará coincidir el hash del archivo recibido con el dado como valor de integridad en la etiqueta del script. Si ambos hash no coinciden, el navegador descartará el archivo jquery.

Por el momento, esta función es compatible con el 91% de los navegadores en todo el mundo. Más detalles sobre caniuse .

5377037
fuente