Tengo una página principal que tiene una Política de seguridad de contenido. El propósito principal de CSP no es prevenir XSS, sino prevenir el acceso a la red. Esta página tiene que ejecutar algún HTML / CSS / JS generado / enviado por el usuario. Estoy ejecutando este contenido de usuario en un iframe utilizando document.write para escribir el contenido del usuario en este iframe.
NOTA: El contenido del usuario que tengo no está cargado o presente en un servidor, pero está disponible dinámicamente, por ejemplo, utilizando algún formulario.
También quiero que el contenido del usuario herede el CSP de la página principal y cualquier iframes creado por el iframe secundario también.
La política aplicada en iframes de acuerdo con la especificación:
La política del recurso de incrustación controla lo que se puede incrustar. Sin embargo, el recurso incrustado está controlado por la política entregada con el recurso o la política del recurso de incrustación si el recurso incrustado es un identificador único global (o un marco srcdoc).
Entonces, el estándar dice que la política no se heredará, porque la página principal no es un identificador único global. No quiero usar srcdoc iframe debido a las siguientes razones
- El html puede ser muy grande
- El código html debe escaparse para usar srcdoc, que parece poco confiable e impuro.
- Soporte del navegador (Edge - bajo consideración )
Pero hay un giro:
Cuando fui a probar esta herencia en los navegadores, el csp en realidad estaba siendo heredado en Chrome, Safari, Firefox pero no en Edge. Esto me parece bastante lógico y correcto.
Aquí está la prueba de muestra que realicé:
<html>
<head>
<!-- CSP just for demo purposes - not the actual csp -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'unsafe-inline'; style-src 'unsafe-inline'"/>
</head>
<body>
<h1>Parent Content</h1>
<p style="font-weight: bold; font-family: arial, sans-serif;">
The image here will be blocked due to CSP (default-src directive).
However the iframe's image will not be blocked on Edge since the CSP is not inherited.
</p>
<img src="http://www.w3schools.com/html/pic_mountain.jpg"/><script>window.addEventListener("DOMContentLoaded", function() {
// creating the child iframe
// Some user controlled HTML content.
var html = "<html><body><h1>Child Content</h1><img src='http://www.w3schools.com/html/pic_mountain.jpg'/></body></html>";
var iframe = document.createElement("iframe");
iframe.setAttribute("height", "400px");
iframe.setAttribute("width", "400px");
document.body.appendChild(iframe); //need to append first to be able to write into the iframe.
var iframeDoc = iframe.contentWindow.document;
iframeDoc.open();
iframeDoc.write(html);
iframeDoc.close();
});
</script>
</body>
</html>
Entonces, finalmente mis preguntas son:
- ¿Puedo depender de esta herencia de CSP a iframe secundario en Chrome, Firefox y Safari? - No puedo encontrar esto documentado en ninguna parte.
- ¿Existe una manera limpia y confiable de poder usar srcdoc con escape y todo? ¿Cuáles son los impactos en el rendimiento de usar srcdoc?
- ¿Hay algún otro método para hacer esto?
Más pensamiento:
El manejo de las especificaciones (y Edge) del CSP que se aplica al iframe aumenta aún más el riesgo de permitir que los scripts 'inseguros en línea' eviten XSS. Porque entonces el atacante puede usar document.write así para activar la creación de iframe en su propio sitio malicioso incluso. Incluso child-src / frame-src 'none', no detiene la creación de iframe utilizando document.write . ¿No es esto muy malo para la seguridad?