Content Security Policy y headers
Directivas de CSP que necesita el SDK, reportes de violación, headers monitoreados y relación con PCI DSS.
Si tu checkout usa Content Security Policy (CSP), debe permitir el snippet de Proteside. El dashboard no genera una CSP por ti: esta página lista lo que el SDK usa realmente en el navegador, para que lo incluyas en la política de la tienda.
Directivas necesarias
| Directiva | Valor | Para qué |
|---|---|---|
script-src | hash, nonce o 'unsafe-inline' para los <script> inline del snippet | Ejecutar el bootstrapper, que incluye la configuración window.__PROTE_INLINE__ cuando la tienda tiene reglas inline. |
script-src | https://cdn.proteside.com | Cargar el shield.js. |
connect-src | https://app.proteside.com | Obtener la configuración (/api/sdk/config) y enviar eventos (/api/sdk/events, mediante fetch y sendBeacon). |
connect-src | 'self' | Leer los headers de seguridad de la propia página (consulta más abajo). |
connect-src | orígenes de los scripts externos de la página (opcional) | Calcular el hash del contenido de los scripts de terceros. |
Sin connect-src para app.proteside.com, el SDK carga y se ejecuta, pero ningún evento llega al dashboard. Sin el
permiso opcional para los orígenes de los scripts, el SDK no calcula el hash de esos scripts: quedan en el inventario
como monitoreados, sin hash, y el navegador genera reportes de violación para esos hosts.
Los scripts inline del snippet
El bootstrapper es inline y debe seguir siéndolo (consulta Instalación del snippet). Elige una forma de autorizarlo:
- Hash (
'sha256-…'): autoriza exactamente ese contenido. El hash cambia cuando cambia el contenido del script: cada vez que vuelves a pegar un snippet de una versión nueva y, si la tienda tiene reglas inline, siempre que vuelves a pegar el snippet después de cambiar reglas o contenedores de Google Tag Manager, porque la configuraciónwindow.__PROTE_INLINE__va al principio del mismo script. Los snippets antiguos, con esa configuración en una etiqueta separada, necesitan un segundo hash para ella. - Nonce: si tu servidor ya genera un nonce por respuesta, agrega el atributo
noncea las etiquetas<script>del snippet al pegarlo en la plantilla. El snippet del dashboard no traenonce. 'unsafe-inline': funciona, pero habilita cualquier script inline y debilita la política. No se recomienda en páginas de pago.
La forma más segura de obtener el hash es dejar que el navegador lo calcule: publica la CSP sin el hash (de preferencia
en modo Content-Security-Policy-Report-Only), abre el checkout y mira el mensaje de violación en la consola. Indica el
valor 'sha256-…' del script bloqueado. Para calcularlo localmente, usa exactamente el contenido entre <script> y
</script>, sin salto de línea al final:
# bootstrapper.js = contenido entre <script> y </script>, copiado del snippet
printf '%s' "$(cat bootstrapper.js)" | openssl dgst -sha256 -binary | openssl base64Ejemplo de header
Un ejemplo para un checkout en mitienda.com con Stripe. Adapta los demás orígenes a tu tienda.
Content-Security-Policy:
default-src 'self';
script-src 'self' 'sha256-BOOTSTRAPPER_HASH' https://cdn.proteside.com https://js.stripe.com;
connect-src 'self' https://app.proteside.com https://api.stripe.com;
frame-src https://js.stripe.com;
img-src 'self' data:;
style-src 'self';
report-uri https://app.proteside.com/api/sdk/csp-report?key=pk_live_3f9c1a7b2e4d6f8a0c1e3b5d7f9a1c3e;
report-to proteside
Reporting-Endpoints: proteside="https://app.proteside.com/api/sdk/csp-report?key=pk_live_3f9c1a7b2e4d6f8a0c1e3b5d7f9a1c3e"El header real va en una sola línea; los saltos de arriba son solo para facilitar la lectura. Si tu snippet usa el formato
antiguo, con window.__PROTE_INLINE__ en una etiqueta <script> separada, agrega también el hash de esa etiqueta.
Si usas el sello estático, este usa atributos style="…" y necesita style-src 'unsafe-inline' o
style-src-attr 'unsafe-inline'. El SDK en sí no necesita style-src ni img-src.
Reportes de violación
Proteside recibe reportes de CSP en la dirección de abajo. No aparece en ninguna pantalla del dashboard; usa tu clave
del SDK en el parámetro key:
https://app.proteside.com/api/sdk/csp-report?key=pk_live_3f9c1a7b2e4d6f8a0c1e3b5d7f9a1c3e- Acepta los dos formatos:
report-uriyreport-to(Reporting API). - El total aparece en Salud del SDK, en la tarjeta Reportes CSP (48 h).
- Una violación de
script-srcoconnect-srchacia un host que no está en el inventario de scripts de la tienda se convierte en la alertaCSP_VIOLATION, con severidad baja. Las violaciones de otras directivas solo entran en el conteo. - Por encima de 600 reportes por minuto por clave, el excedente se descarta.
Para probar una política nueva sin romper el checkout, publícala primero como Content-Security-Policy-Report-Only,
sigue los reportes y después cámbiala a Content-Security-Policy.
Headers de seguridad monitoreados
Para respaldar la detección de cambios en los headers, el SDK lee los headers de seguridad de la página de pago en cada
carga y en cada Proteside.pageChanged():
Content-Security-Policy, Content-Security-Policy-Report-Only, Strict-Transport-Security, X-Frame-Options,
X-Content-Type-Options, Referrer-Policy, Permissions-Policy, Cross-Origin-Opener-Policy,
Cross-Origin-Embedder-Policy, Cross-Origin-Resource-Policy, Access-Control-Allow-Origin y Set-Cookie (este
solo como "no legible en el navegador").
El valor de cada header presente se envía al dashboard. Cuando un valor cambia, el dashboard crea la alerta
HEADER_CHANGED. Los headers aparecen en Evidencias PCI DSS, en la pestaña Cabeceras.
Una solicitud GET extra por pageview
Para leer los headers, el SDK hace una solicitud GET adicional a la URL de la propia página, con las cookies del
cliente y sin caché. Si tu checkout ejecuta alguna acción al recibir un GET (crear un pedido, reservar stock,
generar un cobro), esa acción va a ocurrir dos veces. Asegúrate de que el GET de la página de pago no tenga efectos
secundarios.
Subresource Integrity (SRI)
No uses el atributo integrity en la etiqueta del shield.js. Hoy el SRI no es viable por dos motivos:
- La URL es mutable. La misma dirección recibe cada nueva versión del SDK, así que el hash cambiaría con cada publicación y el navegador empezaría a rechazar el script.
- La CDN no envía headers de CORS. Un
<script integrity crossorigin="anonymous">exige CORS, y el navegador bloquearía la carga.
Como control preventivo, restringe script-src a https://cdn.proteside.com y autoriza el bootstrapper inline por
hash o nonce. El inventario de Proteside registra qué scripts de tu página usan integrity y nonce.
Relación con PCI DSS 4.0
| Requisito | Qué pide | Cómo ayudan Proteside y la CSP |
|---|---|---|
| 6.4.3 | Gestionar los scripts de la página de pago que se ejecutan en el navegador: inventario con justificación, autorización de cada script y garantía de integridad. | El SDK arma el inventario con el hash del contenido; la autorización con justificación se hace en Scripts; las reglas bloquean los scripts no autorizados. La CSP limita desde dónde se pueden cargar scripts. |
| 11.6.1 | Detectar y alertar sobre cambios no autorizados en los headers HTTP y en el contenido de la página de pago, tal como los recibe el navegador. | El SDK lee los headers de seguridad en cada pageview y detecta scripts nuevos o modificados; el dashboard genera HEADER_CHANGED, SCRIPT_INTEGRITY_MISMATCH y las demás alertas. |
Proteside genera evidencias para estos requisitos en Evidencias PCI DSS. La evaluación de cumplimiento sigue siendo responsabilidad de tu evaluador (QSA) o de tu cuestionario de autoevaluación. Consulta Evidencias PCI DSS.