Volver al Blog
Despliegue

Política de seguridad de contenido para aplicaciones web

Diseña, despliega y mantiene una política CSP con responsables claros, observaciones de informe, pruebas de compatibilidad y límites de reversión.

BotBrowser Team

Documentación

Quieres la documentación estructurada de Despliegue?

Este artículo forma parte de la biblioteca editorial. Para pasos de configuración, material de referencia y actualizaciones continuas, entra en la sección de docs.

Una aplicación recibe una política de seguridad de contenido, evalúa un recurso y registra un resultado acotado

La Content Security Policy (CSP, política de seguridad de contenido) es una política de respuesta de la aplicación que indica a los navegadores compatibles qué tipos de recursos puede cargar o ejecutar un documento. Puede reducir el impacto de ciertos errores de inyección al limitar scripts, conexiones, marcos, Workers y otros recursos. No es un programa completo de seguridad: la autorización del servidor, la codificación de salida, la revisión de dependencias, el diseño de sesiones, la seguridad del transporte y la respuesta a incidentes siguen siendo responsabilidades distintas. La especificación CSP Level 3 de W3C define el modelo; la guía CSP de MDN describe decisiones prácticas de despliegue.

Trata CSP como una decisión de producto y despliegue. El equipo de aplicación es responsable de los recursos intencionales; infraestructura, de entregar la respuesta; y cada proveedor, de su propio servicio. Un informe de violación observa una solicitud y una política. No demuestra que hubo un ataque, que la falta de informes implique una aplicación limpia ni que la operación de negocio terminara. Mantener claros estos límites evita presentar un control útil del navegador como una garantía universal.

Usa este artículo para planificar diseño, responsables, despliegue Report-Only, pruebas deterministas, compatibilidad y reversión. Los ejemplos utilizan páginas sintéticas e informes acotados. No ofrecen una forma de debilitar la política para cargar contenido no confiable, recopilar credenciales, neutralizar controles del navegador ni alterar un servicio ajeno. Para otros encabezados de respuesta, consulta la guía de encabezados HTTP personalizados y, para evidencia de versiones, la guía de validación de navegadores.

Define el propósito y los límites

Empieza por los recorridos de usuario que debe proteger la política y los recursos requeridos. Inventaría scripts, estilos, fuentes, imágenes, medios, marcos, Workers, WebSockets, destinos de fetch, formularios y navegación. Incluye recursos incorporados por gestores de etiquetas, pagos, analítica, soporte y Service Workers. El inventario es un documento de propiedad, no una lista copiada de registros del navegador. Para cada entrada, anota propósito, responsable, sensibilidad de datos, entorno y duración prevista.

Separa el límite de aplicación del límite de ejecución del navegador. script-src puede restringir solicitudes de scripts, pero no autoriza una llamada API ni concede privilegios del servidor al script. connect-src restringe conexiones del navegador, no sustituye el control de acceso del destino. Una directiva de marcos puede limitar dónde se inserta un documento, pero no verifica el código ni la política del documento hijo. Registra estas diferencias antes de elegir valores.

Usa la política más acotada que corresponda a un contrato de aplicación propio. Prefiere orígenes explícitos y rutas estables; evita comodines amplios cuando sea viable enumerar menos fuentes. Revisa esquemas, puertos, redirecciones y subdominios: una expresión aparentemente propia puede incluir más hosts de los previstos. Trata cada origen externo como una dependencia con responsable y revisión. Si el equipo no puede explicar por qué lo necesita, no lo agregues solo para silenciar una violación.

Define qué significa pasar para cada recorrido. Puede ser “se muestra la aplicación, carga el módulo aprobado y se bloquea el recurso sintético no aprobado”. No significa “no hubo informes, por tanto la aplicación es segura”. Registra el estado visible esperado, la política entregada al documento final y la evidencia de aplicación necesaria para confirmar la finalización. No conserves secretos, contenido de clientes, cuerpos completos ni atributos del navegador que no sean pertinentes.

PreguntaEvidenciaResponsable y decisión
¿Qué código ejecutable es intencional?URL finales, código en línea y artefacto de despliegueLa aplicación aprueba un nonce, resumen o fuente explícita
¿Qué destinos de red son necesarios?Destinos de fetch, WebSocket, Worker y formularioAplicación y servicio documentan orígenes exactos
¿Qué documentos incrustados son confiables?URL de marcos, redirecciones y responsable hijoProducto aprueba relación y alternativa
¿Qué debe reportarse?Configuración report-to o report-uri y retenciónSeguridad fija privacidad y límites operativos

Elige directivas sin debilitar la confianza

La política debe expresar un modelo de confianza deliberado, no una colección de excepciones. default-src ofrece una base para tipos sin directiva específica. Directivas como script-src, style-src, img-src, font-src, connect-src, frame-src, worker-src, media-src, object-src, base-uri, form-action y frame-ancestors describen decisiones distintas. El soporte y los valores de reserva varían por navegador; prueba las versiones que admite el producto.

Para código ejecutable, haz explícito qué está aprobado. Los nonces son valores por respuesta que el servidor coloca en elementos en línea aprobados y en la política. Un resumen vincula un bloque conocido con un valor exacto de integridad. Los scripts externos también requieren un origen permitido y control de dependencias. No trates un nonce como contraseña ni reutilices uno en respuestas no relacionadas. Autoriza un elemento para una respuesta; no autoriza una API, un usuario ni una cuenta de proveedor.

Revisa con el equipo los permisos de estilos y scripts en línea. Una excepción amplia facilita el despliegue, pero reduce protección. Si un framework antiguo requiere comportamiento en línea, documenta la dependencia, prueba la migración y mantén una excepción temporal y acotada. No añadas unsafe-eval, unsafe-inline, comodines ni un dominio de proveedor completo porque una violación resulte incómoda. Toda excepción necesita razón, responsable, fecha de revisión y alternativa observable.

Otras directivas protegen otros límites. base-uri impide que una URL base inesperada cambie la resolución relativa; form-action restringe envíos; frame-ancestors controla quién puede insertar el documento y es distinta de frame-src; object-src 'none' suele ser apropiada cuando no se necesitan complementos antiguos. upgrade-insecure-requests cambia el tratamiento de URL, pero no corrige todas las integraciones mixtas. Define el efecto esperado antes de habilitar cada directiva.

No confundas CSP con otros encabezados. Permissions Policy controla la delegación de funciones; COOP y COEP definen relaciones entre contextos y recursos; los encabezados de transporte cubren amenazas distintas. CSP los complementa, pero no reemplaza sus garantías. La guía de contextos seguros explica que el estado de seguridad del navegador también es distinto de la política de aplicación. Asigna responsable y aceptación a cada control.

Despliega con evidencia Report-Only

Empieza con Content-Security-Policy-Report-Only en preproducción o una ruta de producción controlada. Report-Only permite que un navegador compatible evalúe una candidata y envíe observaciones sin bloquear recursos. Ayuda a descubrir dependencias omitidas, pero no es una aprobación de seguridad. Puede no haber informes porque el navegador carece de soporte, no se recorrió la ruta, el informe se perdió o el recurso pertenece a otro documento. La ausencia significa “no observado”, no “seguro”.

Asigna una versión y un responsable a cada política candidata. Guarda su texto, ruta o plantilla que la emite, navegadores admitidos, recorrido de prueba y fecha de revisión. Normaliza los informes para guardar solo origen del documento, clase de URI bloqueada, directiva efectiva, disposición, familia de navegador y escenario. Elimina consultas, tokens, cookies, texto de página y otros campos sensibles. El colector debe ser un servicio aprobado, con control de acceso y retención documentada.

Clasifica cada informe frente al inventario. Un URI bloqueado puede ser una denegación intencional, un recurso propio ausente, una dependencia externa, una redirección inesperada o un valor generado por el navegador que no es un recurso de aplicación. Verifica la solicitud y respuesta finales en el entorno aprobado. No agregues automáticamente el origen informado. Averigua quién lo controla, qué datos recibe, si admite la política y qué resultado ve el usuario cuando no carga. El informe prueba una evaluación del navegador, no la confiabilidad del origen.

Ejecuta casos positivos y negativos. El recorrido positivo carga todos los recursos prometidos. El fixture negativo solicita un recurso sintético que la política debe bloquear y comprueba una alternativa visible y acotada. Prueba tanto el encabezado como el comportamiento; un resultado correcto no debe deberse a que la página nunca solicitó el recurso. Usa un origen de prueba controlado por el equipo y conserva solo el resultado breve y la limpieza.

EtapaRespuesta del navegadorEvidenciaRegla de promoción
InventarioAún sin política candidataResponsables y recorridosCada dependencia necesaria tiene dueño
Report-OnlyInforma, pero carga recursosPolítica versionada, informes redactados y resultadosCada informe se clasifica o queda como excepción explícita
Preproducción aplicadaPuede bloquear recursosEncabezado final, resultado visible y matriz de compatibilidadLos recorridos esenciales pasan en navegadores admitidos
Producción aplicadaBloquea fuera del contratoRegistro de despliegue, monitoreo y reversiónResponsable acepta el riesgo de compatibilidad restante

Ejecuta un fixture determinista de recurso bloqueado

El fixture usa una página propia y una imagen bloqueada deliberadamente. Comprueba una alternativa visible, no registra datos privados y elimina el nodo temporal incluso si falla una aserción. Sirve la página por la misma ruta de encabezados que la aplicación candidata. Configura el resultado esperado en el caso de prueba, no a partir del resultado observado. Es una observación del navegador; no demuestra que el servidor rechazara una solicitud, que se impidiera un ataque o que se completara una operación de negocio.

async function checkCspFallback(page, expectedBlocked) {
  const result = await page.evaluate(async expected => {
    const host = document.createElement('section');
    const image = document.createElement('img');
    const status = document.createElement('output');
    let violation = false;
    host.dataset.test = 'owned-csp-blocked-image';
    status.setAttribute('aria-live', 'polite');
    status.textContent = 'Esperando el resultado de la política';
    image.alt = 'Recurso propio del fixture';
    const outcome = new Promise(resolve => {
      document.addEventListener(
        'securitypolicyviolation',
        event => {
          if (event.blockedURI.endsWith('/fixtures/csp-owned-image.png')) {
            violation = true;
            resolve('blocked');
          }
        },
        { once: true }
      );
      image.addEventListener('load', () => resolve('loaded'), { once: true });
      image.addEventListener('error', () => resolve('error'), { once: true });
    });
    image.src = '/fixtures/csp-owned-image.png';
    host.append(image, status);
    document.body.append(host);
    let timeoutId;
    const timeout = new Promise(resolve => {
      timeoutId = window.setTimeout(() => resolve('not-observed'), 5000);
    });
    const observed = await Promise.race([outcome, timeout]);
    window.clearTimeout(timeoutId);
    const blocked = violation;
    status.textContent = blocked
      ? 'Alternativa: la política de aplicación bloqueó la imagen'
      : observed === 'loaded'
        ? 'Control: el fixture propio cargó'
        : 'El fixture falló sin una violación de política';
    const passed = expected
      ? observed !== 'error' && observed !== 'not-observed' && violation
      : observed === 'loaded' && !violation;
    return { marker: host.dataset.test, observed, blocked, passed };
  }, expectedBlocked);

  try {
    if (!result.passed) throw new Error(`Unexpected CSP fixture result: ${result.observed}`);
    return result;
  } finally {
    await page.evaluate(() => document.querySelector('[data-test="owned-csp-blocked-image"]')?.remove());
  }
}

Sirve /fixtures/csp-owned-image.png desde el stub propio de pruebas con una respuesta de imagen válida y pequeña. La política de control permite img-src 'self', por lo que la imagen debe cargar; la candidata usa img-src 'none', por lo que el navegador emite securitypolicyviolation y se registra la alternativa visible. Si no aparece el evento esperado, registra “no observado” e investiga política, compatibilidad y fixture. No conviertas un error de red o de política en un aprobado. El fallo determinista debe dejar limpio el contexto y el directorio de artefactos.

Ejecuta el fixture una vez con la política de control y otra con la candidata, pasando false y true respectivamente. Mantén separados los recibos. “Bloqueado” solo es útil si el control demuestra que el stub propio era accesible y la candidata informa una violación de política. Incluye URL final, versión de política, versión del navegador, marcador, resultado visible y limpieza. No guardes cookies, encabezados de autorización, registros completos ni una respuesta de producción copiada.

Si configuración, aserción y limpieza pueden fallar, conserva como principal el primer error del recorrido. Informa la limpieza en un campo distinto y cierra página y contexto en un finalizador. Cada reintento usa contexto e informe nuevos. Un aprobado posterior no elimina la incertidumbre de una solicitud previa, sobre todo con Report-Only, donde el recurso pudo llegar al servicio real. Usa un origen sintético para evitar mutaciones remotas.

Valida compatibilidad y responsables

Prueba en navegadores, sistemas, modos de documento y rutas admitidos por el equipo. Incluye redirecciones, caché, Service Workers, scripts de módulo, Workers, marcos, formularios e importaciones dinámicas cuando se usen. La política en un archivo de configuración perimetral no demuestra que el navegador la recibió. Inspecciona la respuesta final después de redirecciones y confirma qué documento posee la política. Un documento anidado puede tener política y decisiones de recursos propias.

Haz explícitos los contratos. Aplicación define recursos necesarios y alternativa UX; alojamiento o CDN confirma que el encabezado llega a todas las rutas canónicas; seguridad determina informes, retención e incidentes; proveedores confirman sus orígenes, redirecciones y manejo de datos; el responsable de publicación resuelve conflictos y registra la versión aceptada. Si el servicio es opcional, documenta la alternativa; si es esencial, no promociones hasta que el contrato sea compatible.

Revisa las interacciones con caché y plantillas. Un nonce por respuesta no debe reutilizarse, y el HTML almacenado debe llevar el nonce que coincide con su política. Un colector no debe exponer valores sensibles de consultas. Un Service Worker puede servir un documento antiguo, por lo que prueba contexto limpio y contexto recurrente cuando corresponda. El aislamiento de estado del navegador facilita recorridos repetibles, pero no elimina registros del servidor ni repara un despliegue obsoleto.

Revisa cambios de política como código e infraestructura. Compara directivas, fuentes, generación de nonce o resumen, ruta de respuesta, destino de informes y esquema de recibo. Asigna dueño a cada fuente añadida. Pon fecha de caducidad o revisión a las excepciones. Retira una fuente solo cuando un recorrido positivo confirme que ya no se usa y un despliegue aprobado la haya eliminado. Un flujo limpio de informes sin recorrer la aplicación no demuestra que se retiró una dependencia.

Caso de compatibilidadComprobaciónSi falla
Inicio en líneaNonce o resumen coincide con la respuestaCorrige generación o usa un módulo externo propio
Importación de módulo o WorkerURL final y directiva aplicableAñade fuente propia exacta o usa alternativa admitida
Marco o formularioOrigen hijo, redirecciones y frame-src, frame-ancestors, form-actionCoordina con su dueño; no añadas comodín global
Caché o respuesta de Service WorkerPolítica y recurso pertenecen a la candidataPurga por proceso aprobado o espera expiración controlada

Supervisa, revierte y mantén

Activa la aplicación por rutas o grupos acotados primero. Supervisa recursos bloqueados por versión, ruta, familia de navegador y dependencia. Agrega solo lo necesario para no conservar contenido del usuario. Un aumento puede indicar dependencia nueva, desajuste de caché, redirección, cambio de navegador o problema del colector. Compáralo con un recorrido positivo conocido antes de modificar la política. El volumen de informes no es una métrica universal de seguridad o disponibilidad.

Prepara la reversión antes de aplicar. Conserva la política y versión de aplicación anteriores y los recibos. Si falla un recorrido esencial, restaura juntas la política conocida y la ruta de aplicación, y vuelve a ejecutar los fixtures positivo y negativo. Si el código depende del recurso nuevo, protégelo con una alternativa en tiempo de ejecución o publica la versión compatible. La reversión no debe retirar transporte seguro, autorización ni registros necesarios para explicar el fallo.

Después de revertir, conserva los informes candidatos como históricos. No borres evidencia ni presentes Report-Only como resultado aplicado. Abre un seguimiento acotado para responsables del recurso, política o publicación. La próxima candidata debe cambiar una condición conocida y repetir el fixture, para distinguir fuente ausente, nonce erróneo, redirección, caché o alternativa de aplicación.

Mantén actualizado el registro: encabezado y rutas, versión, responsables de fuentes, destino de informes, retención, navegadores admitidos, excepciones y fecha de revisión. Revalida tras actualizar el framework, cambiar reglas CDN, proveedor, marco, Worker o host canónico. CSP es parte del contrato desplegado, así que documentación obsoleta también es un riesgo de mantenimiento.

Qué puede validar BotBrowser

Los contextos controlados de BotBrowser permiten ejecutar un recorrido de aplicación autorizado con estado de navegador limpio o declarado, observar si el navegador bloquea un recurso sintético y comparar una alternativa visible entre ejecuciones repetibles. La documentación de aislamiento de varias cuentas de BotBrowser describe BrowserContexts aislados y los límites del estado que gestionan. Esto valida la parte visible del caso CSP: URL final, metadatos de política que la prueba esté autorizada a consultar, resultado de carga o bloqueo y recibo de limpieza.

BotBrowser no redacta ni despliega encabezados, elige una lista segura para la aplicación, valida autorización del servidor o cadena de suministro, ni demuestra que no haya vulnerabilidades de inyección. No puede hacer confiable un recurso ajeno, conceder una excepción al proveedor ni garantizar igual soporte de directivas en todo navegador. Tampoco prueba que se creara un registro, se aceptara un pago, se revocara una sesión o no ocurriera un incidente. Para esos hechos se requiere evidencia de aplicación, servicio, infraestructura y seguridad.

BotBrowser soporta recorridos autorizados que observan el bloqueo de un recurso en un contexto aislado, pero no puede redactar ni desplegar la política, validar la autorización del servidor ni demostrar un resultado de seguridad. Mantén acotados sus recibos: escenario, versión de política, URL final, compilación, resultado visible, clasificación de ruta sintética y limpieza. No incluyas contenido de clientes, credenciales, cookies ni cargas completas. Etiqueta el resultado como “observación de política del navegador” y enlaza evidencia independiente para afirmaciones de negocio. Un contexto limpio es una condición de ejecución, no un mecanismo de borrado del servidor ni una certificación de seguridad.

Antes de publicar, los responsables deben confirmar cuatro límites: un informe no prueba un ataque; la falta de informes no prueba seguridad; un recurso bloqueado no prueba rechazo o eliminación por el servidor; y observar con BotBrowser no sustituye autorización ni revisión de dependencias. Registra política aceptada, compatibilidad, alternativa, responsable de monitoreo y artefacto de reversión. Así se mejora la protección sin debilitarla para cargar una dependencia desconocida.

Repite los mismos recorridos cuando cambien la política o una dependencia propia. Una comparación estrecha y versionada ayuda a identificar si cambió la decisión del navegador, la alternativa de la aplicación o el resultado de un servicio separado.

BotBrowser Team

Fuentes

#Content Security Policy#CSP#Seguridad Web#Aplicaciones De Navegador

Lleva BotBrowser de la investigación a producción

Usa estas guías para entender el modelo y después avanzar hacia validación multiplataforma, contextos aislados y despliegue de navegador preparado para escalar.