Una Content Security Policy indica al navegador desde qué orígenes puede cargar una página scripts, estilos, imágenes y otros recursos, y es la principal defensa en profundidad contra el cross-site scripting (XSS). Se envía en la cabecera Content-Security-Policy como una lista de directivas separadas por punto y coma. Cree una con el generador de cabeceras CSP y evalúe un sitio real con el analizador de cabeceras de seguridad. Las cadenas de respaldo de esta página proceden de la especificación CSP Level 3.
Directivas de obtención y sus respaldos
Si falta una directiva, el navegador usa la siguiente de su cadena de respaldo; si no hay ninguna, ese tipo de recurso no tiene restricciones.
| Directiva | Controla | Recurre a |
|---|---|---|
default-src |
Respaldo de todas las directivas de obtención siguientes | nada |
script-src |
JavaScript (elementos, atributos, eval) |
default-src |
script-src-elem |
Solo elementos <script> |
script-src → default-src |
script-src-attr |
Manejadores de eventos en línea como onclick |
script-src → default-src |
style-src |
Hojas de estilo y estilos en línea | default-src |
style-src-elem |
<style> y <link rel="stylesheet"> |
style-src → default-src |
style-src-attr |
Atributos style="..." |
style-src → default-src |
img-src |
Imágenes y favicons | default-src |
font-src |
Fuentes web | default-src |
connect-src |
fetch, XHR, WebSocket, EventSource, sendBeacon |
default-src |
media-src |
<audio>, <video>, pistas de texto |
default-src |
object-src |
Plugins <object> y <embed> |
default-src |
manifest-src |
Manifiesto de aplicación web | default-src |
child-src |
Marcos y workers (si faltan las dos siguientes) | default-src |
frame-src |
Contenido de <iframe> y <frame> |
child-src → default-src |
worker-src |
Workers web, compartidos y de servicio | child-src → script-src → default-src |
Directivas sin respaldo
default-src no las cubre; si las omite, no hay ninguna restricción.
| Directiva | Controla | Valor típico |
|---|---|---|
base-uri |
URL permitidas en <base href> |
'self' o 'none' |
form-action |
Adónde pueden enviarse los formularios | 'self' |
frame-ancestors |
Quién puede incrustar esta página en un marco (clickjacking) | 'none' o 'self'; sustituye a X-Frame-Options |
sandbox |
Aplica a la página las restricciones de un iframe con sandbox | sandbox allow-scripts |
upgrade-insecure-requests |
Reescribe las URL http: de los subrecursos a https: |
sin valor |
report-to |
Grupo de la Reporting API que recibe los informes de infracción | un nombre de grupo de Reporting-Endpoints |
report-uri |
URL que recibe los informes de infracción (obsoleta, aún muy compatible) | /csp-report |
require-trusted-types-for |
Obliga a usar Trusted Types en los sumideros de XSS del DOM | 'script' |
trusted-types |
Nombra las políticas de Trusted Types permitidas | nombres de políticas |
Expresiones de origen
| Expresión | Permite |
|---|---|
'none' |
Nada (debe ser el único valor) |
'self' |
El origen de la propia página (mismo esquema, host y puerto) |
https: |
Cualquier URL con ese esquema; data:, blob: y otros funcionan igual |
example.com |
Ese host; *.example.com cubre sus subdominios, no el dominio desnudo |
https://cdn.example.com/js/ |
Ese prefijo de ruta en ese host |
'unsafe-inline' |
<script>/<style> en línea y manejadores de eventos; se ignora si hay un nonce o un hash |
'unsafe-eval' |
eval(), new Function() y temporizadores con cadenas |
'wasm-unsafe-eval' |
Compilar WebAssembly sin permitir el eval de JavaScript |
'nonce-<base64>' |
Elementos cuyo atributo nonce coincide; genere un valor aleatorio nuevo en cada respuesta |
'sha256-<base64>' |
Contenido en línea cuyo hash coincide (sha384- y sha512- también valen) |
'strict-dynamic' |
Scripts cargados por un script ya confiable; las listas de hosts y esquemas se ignoran entonces |
'unsafe-hashes' |
Permite que los hashes coincidan con manejadores de eventos y atributos style |
'report-sample' |
Incluye los primeros 40 caracteres del código bloqueado en los informes |
Reglas de entrega
- Cabecera o meta.
<meta http-equiv="Content-Security-Policy" content="...">funciona, pero ahí se ignoranframe-ancestors,report-uriysandbox, y el modo de solo informe no se puede fijar por meta. - Solo informe.
Content-Security-Policy-Report-Onlyenvía informes de infracción sin bloquear nada: despliegue así primero cualquier política nueva. - Varias políticas. Si una respuesta lleva dos cabeceras CSP, un recurso debe superar ambas; añadir una política solo puede endurecer, nunca relajar.
- Compruebe lo que se envía. Inspeccione las cabeceras reales de una página con el visor de cabeceras HTTP.
Políticas de partida
| Objetivo | Política |
|---|---|
| Blindar un sitio estático | default-src 'self'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'; form-action 'self' |
| Scripts estrictos con nonce | script-src 'nonce-R4nd0m' 'strict-dynamic'; object-src 'none'; base-uri 'none' |
| Permitir un CDN e imágenes de cualquier sitio por HTTPS | default-src 'self'; script-src 'self' https://cdn.example.com; img-src 'self' https: data: |
| Solo frenar el clickjacking | frame-ancestors 'self' |
| API que solo devuelve JSON | default-src 'none'; frame-ancestors 'none' |
El nonce R4nd0m representa un valor nuevo e impredecible generado en cada respuesta; un nonce fijo no protege nada.