Acerca de este problema HTML
El atributo sandbox es una de las características de seguridad más poderosas disponibles para los elementos <iframe>. Cuando está presente sin valor (o con tokens específicos), aplica un conjunto estricto de restricciones al contenido embebido: bloquea scripts, envío de formularios, popups, acceso same-origin y más. Puedes relajar selectivamente estas restricciones añadiendo tokens separados por espacios como allow-scripts, allow-forms o allow-popups.
El problema surge específicamente cuando allow-scripts y allow-same-origin se usan juntos. El token allow-scripts permite que la página embebida ejecute JavaScript, mientras que allow-same-origin le permite mantener su origen original (en lugar de ser tratada como proveniente de un origen único y opaco). Con ambos habilitados, el JavaScript de la página embebida puede acceder al DOM de la página padre a través de window.parent (si comparten el mismo origen) o, más críticamente, puede usar JavaScript para eliminar programáticamente el atributo sandbox de su propio elemento <iframe>. Una vez que se elimina el atributo, todas las restricciones de sandboxing se levantan, haciendo que el atributo sandbox sea completamente inútil.
Por esto el validador de W3C marca esta combinación: no es técnicamente HTML inválido, pero es un anti-patrón de seguridad que hace que el sandboxing sea inefectivo. La especificación HTML de WHATWG advierte explícitamente contra esta combinación por la misma razón.
Cómo solucionarlo
La solución depende de lo que el contenido embebido realmente necesite:
-
Si la página embebida necesita scripts pero no acceso same-origin: Elimina
allow-same-origin. La página aún puede ejecutar JavaScript pero será tratada como un origen único, evitando que acceda a cookies, almacenamiento o el DOM del marco padre. -
Si la página embebida necesita acceso same-origin pero no scripts: Elimina
allow-scripts. La página mantiene su origen pero no puede ejecutar ningún JavaScript. -
Si crees que ambos son requeridos: Reconsidera si el sandboxing es el enfoque correcto. Si el contenido embebido verdaderamente necesita tanto ejecución de scripts como acceso same-origin, el atributo
sandboxno proporciona ningún beneficio de seguridad significativo, y es posible que quieras usar otros mecanismos de seguridad como headersContent-Security-Policyen su lugar.
Siempre sigue el principio de menor privilegio: otorga solo los permisos que el contenido embebido estrictamente requiere.
Ejemplos
❌ Incorrecto: usar tanto allow-scripts como allow-same-origin
<iframe
src="https://example.com/widget"
sandbox="allow-scripts allow-same-origin">
</iframe>
Esto activa la advertencia del validador porque la página embebida puede usar su acceso a scripts combinado con su origen preservado para escapar completamente del sandbox.
❌ Incorrecto: ambas banderas presentes junto con otros tokens
<iframe
src="https://example.com/widget"
sandbox="allow-forms allow-scripts allow-same-origin allow-popups">
</iframe>
Incluso con tokens adicionales, la presencia de tanto allow-scripts como allow-same-origin aún derrota el sandbox.
✅ Correcto: permitir scripts sin acceso same-origin
<iframe
src="https://example.com/widget"
sandbox="allow-scripts">
</iframe>
La página embebida puede ejecutar JavaScript pero es tratada como un origen opaco único, evitando que acceda a recursos de la página padre o elimine su propio sandbox.
✅ Correcto: permitir solo los permisos necesarios
<iframe
src="https://example.com/widget"
sandbox="allow-scripts allow-forms allow-popups">
</iframe>
Esto otorga capacidades de ejecución de scripts, envío de formularios y popups mientras mantiene el contenido en sandbox en un origen único.
✅ Correcto: usar un sandbox vacío para máxima restricción
<iframe
src="https://example.com/widget"
sandbox="">
</iframe>
Un atributo sandbox vacío aplica todas las restricciones: sin scripts, sin envío de formularios, sin popups, sin acceso same-origin y más. Esta es la opción más segura cuando el contenido embebido es puramente estático.
✅ Correcto: eliminar el sandbox cuando no proporciona beneficio real
<iframe
src="https://example.com/widget"
title="Example widget">
</iframe>
Si genuinamente necesitas tanto ejecución de scripts como acceso same-origin, es más honesto omitir sandbox completamente y confiar en otras medidas de seguridad, en lugar de incluir un atributo que proporciona una falsa sensación de seguridad.
Encuentra problemas como este automáticamente
Rocket Validator escanea miles de páginas en segundos, detectando problemas de HTML en todo tu sitio web.
Más información: