我有一个父页面,上面有内容安全策略。CSP的主要目的不是防止XSS,而是防止网络访问。此页面必须运行一些用户生成/提交的 HTML/CSS/JS。我在 iframe 中运行此用户内容,方法是使用 document.write 将用户内容写入此 iframe。
注意:我拥有的用户内容没有上传或出现在服务器上,但可以动态使用——比如使用某种形式。
我还希望用户内容继承父页面的 CSP 以及由子 iframe 创建的任何 iframe。
根据规范应用于 iframe 的策略:
嵌入资源的策略控制可以嵌入的内容。然而,嵌入资源由与资源一起提供的策略控制,或者如果嵌入资源是全局唯一标识符(或 srcdoc 框架),则由嵌入资源的策略控制。
因此,该标准表示该策略不会被继承,因为父页面不是全局唯一标识符。由于以下原因,我不想使用 srcdoc iframe
- html 可能非常大
- 需要对 html 进行转义才能使用 srcdoc,这似乎不可靠且不干净。
- 浏览器支持(边缘 -正在考虑中)
但是有一个转折:
当我继续在浏览器上测试这个继承时,csp 实际上是在 Chrome、Safari、Firefox 上继承的,但不是 Edge。这对我来说似乎很合乎逻辑和正确。
这是我执行的示例测试:
<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>
所以,最后我的问题是:
- 我可以依赖 CSP 的这种继承到 Chrome、Firefox 和 Safari 上的子 iframe 吗?- 我在任何地方都找不到这个记录。
- 是否有一种干净可靠的方法可以使用 srcdoc 进行转义和所有操作?使用 srcdoc 对性能有何影响?
- 有没有其他方法可以做到这一点?
更多思考:
规范(和 Edge)对应用于 iframe 的 CSP 的处理进一步增加了允许脚本“不安全内联”以防止 XSS 的风险。因为这样攻击者甚至可以像这样使用 document.write 来触发创建 iframe 到他自己的恶意站点。即使 child-src/frame-src 'none',也不会停止使用 document.write 创建 iframe。这对安全不是很不利吗?