Cross-Origin-Opener-Policy (COOP) y Cross-Origin-Embedder-Policy (COEP) son dos cabeceras de respuesta HTTP introducidas por Chromium en 2020 y hoy soportadas por todos los navegadores principales (Chrome 83+, Firefox 79+, Safari 15.2+). COOP controla si una página comparte su grupo de contexto de navegación con ventanas que abre o que la abrieron; COEP controla si la página puede cargar subrecursos cross-origin. Al combinar COOP: same-origin con COEP: require-corp o credentialless se entra en modo "cross-origin isolated", requerido para usar SharedArrayBuffer, performance.measureUserAgentSpecificMemory() y los timers de alta precisión de performance.now(). Forman parte del endurecimiento post-Spectre del navegador, junto con Cross-Origin-Resource-Policy (CORP).
¿Por qué se introdujeron COOP y COEP?
En enero de 2018 las vulnerabilidades de canal lateral de CPU Spectre y Meltdown (CVE-2017-5753, CVE-2017-5715, CVE-2017-5754) mostraron que un JavaScript malicioso puede leer memoria de otros orígenes dentro del mismo proceso de renderizado. Los navegadores deshabilitaron SharedArrayBuffer y bajaron la resolución de performance.now() de microsegundos a 100 µs. COOP y COEP permiten a un sitio pedir explícitamente un contexto aislado por proceso y limpio en cross-origin para reactivar esas APIs.
¿Qué hace Cross-Origin-Opener-Policy (COOP)?
unsafe-none— por defecto. Permite acceso awindow.openerentre orígenes.same-origin-allow-popups— los popups que tú abres mantienen referencia; los documentos cross-origin que intenten acceder a ti quedan aislados.same-origin— aislamiento total. Necesario para cross-origin isolation.
Cross-Origin-Opener-Policy: same-origin¿Qué hace Cross-Origin-Embedder-Policy (COEP)?
unsafe-none— por defecto.require-corp— cada subrecurso cross-origin debe optar porCross-Origin-Resource-Policy: cross-origino CORS válido.credentialless— desde Chrome 96 (octubre 2021). Las peticiones cross-origin van sin cookies; el recurso no necesita optar.
Cross-Origin-Embedder-Policy: require-corp¿Qué es cross-origin isolation?
if ( self.crossOriginIsolated ) {
// SharedArrayBuffer y timers de alta resolución disponibles
}Sin aislamiento, los navegadores modernos bloquean new SharedArrayBuffer() y redondean performance.now() a 100 µs.
¿Cuándo necesito COOP y COEP en WordPress?
- No los necesitas en un sitio de contenido, blog o WooCommerce estándar. Activarlos puede romper embeds (YouTube, Google Maps, Stripe Checkout, Facebook).
- Los necesitas si despliegas WebAssembly multi-threaded (Photopea, Figma, FFmpeg.wasm), edición de vídeo en el navegador, juegos compilados con Emscripten o medición precisa de rendimiento.
- Solo COOP (
same-origin-allow-popups) es útil en páginas de login y dashboards contra tabnabbing.
¿Cómo configuro COOP y COEP en WordPress?
Apache:
<IfModule mod_headers.c>
Header set Cross-Origin-Opener-Policy "same-origin"
Header set Cross-Origin-Embedder-Policy "require-corp"
Header set Cross-Origin-Resource-Policy "same-site"
</IfModule>Nginx:
add_header Cross-Origin-Opener-Policy "same-origin" always;
add_header Cross-Origin-Embedder-Policy "require-corp" always;
add_header Cross-Origin-Resource-Policy "same-site" always;¿Qué se rompe al activar COEP: require-corp?
- iframes de YouTube y Vimeo (salvo en modo
credentialless). - Google Fonts desde
fonts.gstatic.comsin CORS. - Avatares externos como Gravatar.
- Píxeles de seguimiento, Stripe.js, hCaptcha.
DevTools » Network » columna "Blocked" muestra los culpables. credentialless alivia el requisito.
¿Cómo compruebo si mi sitio está cross-origin isolated?
- Abre el sitio en Chrome.
- DevTools (F12) » Application » Frames » top » revisa "Cross-Origin Isolated: Yes".
- O ejecuta
self.crossOriginIsolateden la consola.
Qué comprueba InspectWP
InspectWP analiza cada cabecera HTTP de respuesta de la página rastreada e informa de la presencia y valor de Cross-Origin-Opener-Policy, Cross-Origin-Embedder-Policy y Cross-Origin-Resource-Policy en la sección Seguridad. La ausencia se marca como aviso, no crítico, porque la mayoría de sitios de contenido no necesita aislamiento completo.