¿Cómo funciona la Política de Seguridad de Contenido?


Estoy recibiendo un montón de errores en la consola del desarrollador:

Se negó a evaluar una cadena

Se negó a ejecutar el script en línea porque viola la siguiente directiva de Política de Seguridad de Contenido

Se negó a cargar el script

Se negó a cargar la hoja de estilos

¿De qué se trata todo esto? ¿Cómo funciona la Política de Seguridad de Contenido? ¿Cómo uso el encabezado HTTP Content-Security-Policy?

Específicamente, cómo hacerlo...

  1. ...permitir múltiples fuentes?
  2. ...¿usar directivas diferentes?
  3. ...¿usar varias directivas?
  4. ...¿manejar puertos?
  5. ...manejar diferentes protocolos?
  6. ...permitir file:// protocolo?
  7. ...¿usar estilos en línea, scripts y etiquetas <style> y <script>?
  8. ...permitir eval()?

Y finalmente:

  1. ¿Qué significa exactamente 'self'?
Author: Michał Perłakowski, 2015-05-16

2 answers

La meta-etiqueta Content-Security-Policy le permite reducir el riesgo de ataques XSS al permitirle definir desde dónde se pueden cargar los recursos, evitando que los navegadores carguen datos desde cualquier otra ubicación. Esto hace que sea más difícil para un atacante inyectar código malicioso en su sitio.

Me golpeé la cabeza contra una pared de ladrillo tratando de averiguar por qué estaba recibiendo errores CSP uno tras otro, y no parecía haber instrucciones concisas y claras sobre cómo funciona. Tan aquí está mi intento de explicar algunos puntos de CSP brevemente, concentrándome principalmente en las cosas que encontré difíciles de resolver.

Por brevedad no escribiré la etiqueta completa en cada muestra. En su lugar, solo mostraré la propiedad content, por lo que una muestra que dice content="default-src 'self'" significa esto:

<meta http-equiv="Content-Security-Policy" content="default-src 'self'">

1. ¿Cómo permitir múltiples fuentes?

Simplemente puede enumerar sus fuentes después de una directiva como una lista separada por espacios:

content="default-src 'self' https://example.com/js/"

Tenga en cuenta que no hay citas alrededor parámetros distintos de los especiales, como 'self'. Además, no hay dos puntos (:) después de la directiva. Solo la directiva, luego una lista de parámetros separados por espacios.

Todo lo que esté por debajo de los parámetros especificados está permitido implícitamente. Eso significa que en el ejemplo anterior estas serían fuentes válidas:

https://example.com/js/file.js
https://example.com/js/subdir/anotherfile.js

Estos, sin embargo, no serían válidos:{[39]]}

http://example.com/js/file.js
^^^^ wrong protocol

https://example.com/file.js
                   ^^ above the specified path

2. ¿Cómo usar diferentes directivas, qué hacen cada una?

La mayoría las directivas comunes son:

  • default-src la política predeterminada para cargar javascript, imágenes, CSS, fuentes, solicitudes AJAX, etc
  • script-src define fuentes válidas para archivos javascript
  • style-src define fuentes válidas para archivos css
  • img-src define fuentes válidas para imágenes
  • connect-src define destinos válidos para XMLHttpRequest (AJAX), WebSockets o EventSource. Si se realiza un intento de conexión a un host que no está permitido aquí, el navegador emulará un 400 error

Hay otros, pero estos son los que es más probable que necesite.

3. ¿Cómo usar varias directivas?

Usted define todas sus directivas dentro de una meta-etiqueta terminándolas con un punto y coma (;):

content="default-src 'self' https://example.com/js/; style-src 'self'"

4. Cómo manejar los puertos?

Todo menos los puertos predeterminados deben ser permitidos explícitamente agregando el número de puerto o un asterisco después del dominio permitido:

content="default-src 'self' https://ajax.googleapis.com http://example.com:123/free/stuff/"

El el resultado sería:

https://ajax.googleapis.com:123
                           ^^^^ Not ok, wrong port

https://ajax.googleapis.com - OK

http://example.com/free/stuff/file.js
                 ^^ Not ok, only the port 123 is allowed

http://example.com:123/free/stuff/file.js - OK

Como mencioné, también puede usar un asterisco para permitir explícitamente todos los puertos:

content="default-src example.com:*"

5. ¿Cómo manejar diferentes protocolos?

De forma predeterminada, solo se permiten protocolos estándar. Por ejemplo, para permitir WebSockets ws:// tendrás que permitirlo explícitamente:

content="default-src 'self'; connect-src ws:; style-src 'self'"
                                         ^^^ web sockets are now allowed on all domains and ports

6. ¿Cómo permitir el protocolo de archivos file://?

Si tratas de definirlo como tal, no funcionará. En su lugar, lo permitirá con el filesystem parámetro:

content="default-src filesystem"

7. ¿Cómo usar scripts en línea y definiciones de estilo?

A menos que se permita explícitamente, no puede usar definiciones de estilo en línea, código dentro de etiquetas <script> o en propiedades de etiquetas como onclick. Les permites así:

content="script-src 'unsafe-inline'; style-src 'unsafe-inline'"

También tendrás que permitir explícitamente imágenes codificadas en línea base64:

content="img-src data:"

8. Cómo permitir eval()?

Estoy seguro de que mucha gente diría que no, ya que 'eval es malo' y la la causa más probable del inminente fin del mundo. Esa gente estaría equivocada. Claro, definitivamente puede perforar agujeros importantes en la seguridad de su sitio con eval, pero tiene casos de uso perfectamente válidos. Solo tienes que ser inteligente al usarlo. Lo permites así:

content="script-src 'unsafe-eval'"

9. ¿Qué significa exactamente 'self'?

Puede tomar 'self' como localhost, sistema de archivos local, o cualquier cosa en el mismo host. No significa nada de eso. Significa fuentes que tienen la el mismo esquema (protocolo), el mismo host y el mismo puerto que el archivo en el que se define la directiva de contenido. Servir su sitio a través de HTTP? No hay https para usted, a menos que lo defina explícitamente.

He usado 'self' en la mayoría de los ejemplos, ya que generalmente tiene sentido incluirlo, pero de ninguna manera es obligatorio. Déjalo fuera si no lo necesitas.

Pero espera un minuto! ¿No puedo usar content="default-src *" y terminar con esto?

No. Además de las obvias vulnerabilidades de seguridad, esto lo dejaría también no funcionará como esperarías. Aunque algunos documentos afirman que permite cualquier cosa, eso no es cierto. No permite inlining o evaluaciones, por lo que para realmente, realmente hacer que su sitio sea más vulnerable, usaría esto:

content="default-src * 'unsafe-inline' 'unsafe-eval'"

... pero confío en que no lo harás.

Lectura adicional:

Http://content-security-policy.com

Http://en.wikipedia.org/wiki/Content_Security_Policy

 386
Author: Schlaus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-01 15:27:01

APACHE2 MOD_HEADERS

También puede habilitar Apache2 mod_headers, en Fedora ya está habilitado por defecto, si usa Ubuntu/Debian habilítelo así:

# First enable headers module for Apache2, 
# then restart the Apache2 service   
a2enmod headers
apache2 -k graceful

En Ubuntu / Debian puede configurar encabezados en el archivo /etc/apache2/conf-enabled/security.conf

#
# Setting this header will prevent MSIE from interpreting files as something
# else than declared by the content type in the HTTP headers.
# Requires mod_headers to be enabled.
# 
#Header set X-Content-Type-Options: "nosniff"

#
# Setting this header will prevent other sites from embedding pages from this
# site as frames. This defends against clickjacking attacks.
# Requires mod_headers to be enabled.
#
Header always set X-Frame-Options: "sameorigin"
Header always set X-Content-Type-Options nosniff
Header always set X-XSS-Protection "1; mode=block"
Header always set X-Permitted-Cross-Domain-Policies "master-only"
Header always set Cache-Control "no-cache, no-store, must-revalidate"
Header always set Pragma "no-cache"
Header always set Expires "-1"
Header always set Content-Security-Policy: "default-src 'none';"
Header always set Content-Security-Policy: "script-src 'self' www.google-analytics.com adserver.example.com www.example.com;"
Header always set Content-Security-Policy: "style-src 'self' www.example.com;"

Nota: Esta es la parte inferior del archivo, solo las últimas 3 entradas son configuraciones de CSP.

El primer parámetro es la directiva, el segundo son las fuentes que se listarán en blanco. He añadido Google analytics y un adserver, que podrías tener. Además encontré que si tienes alias, por ejemplo, www.example.com y example.com configurado en Apache2 usted debe añadirlos a la lista blanca también.

El código en línea se considera dañino, debe evitarlo. Copie todos los javascript y css para separar los archivos y agréguelos a la lista blanca.

Mientras estás en ello, puedes echar un vistazo a las otras configuraciones de encabezado e instalar mod_security

Más lectura:

Https://developers.google.com/web/fundamentals/security/csp /

Https://www.w3.org/TR/CSP /

 10
Author: Erik Hendriks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-25 17:20:53