gpt4 book ai didi

javascript - 没有用于跨源 iframe 的不安全内联注册 onload 处理程序的 CSP

转载 作者:行者123 更新时间:2023-12-03 02:12:43 24 4
gpt4 key购买 nike

我们的动机

我们正在使用 script-src: 'self' 实现 CSP 2.0(尤其是没有 'unsafe-inline')。在某些地方,我们渲染具有跨源内容的 iframe,我们需要知道它们何时加载。在 CSP 之前我们会简单地写

<iframe src="https://some.cross/origin/content" onload="this.complete = true"/>
<script>
var iframe = document.querySelector('iframe');
function loaded() { /* whatever happens when the iframe is loaded */ }
if (iframe.complete) {
loaded();
} else {
iframe.addEventListener('load', loaded);
}
</script>

但是,如果没有'unsafe-inline',我们就不能再使用onload="this.complete = true"了。如果事件监听器已经触发,那么简单地附加事件监听器是行不通的:

<iframe src="https://some.cross/origin/content"/>
<script>
var iframe = document.querySelector('iframe');
function loaded() { /* ... */ }
// if the load event does not fire because it fired before
// loaded() will never be executed
iframe.addEventListener('load', loaded);
</script>

我们尝试了什么

现在,解决方案是查看 iframe 内容 document.readystate 内部,但对于跨源内容,我们会在这里遇到安全异常。

随机数不适用于内联处理程序(至少在 CSP 2.0 中),因此简单地为内联处理程序提供随机数不是一种选择。

我们的最终想法是将所有 onload iframe 重写为 javascript 插入的元素,因为我们可以在插入元素之前附加加载处理程序,例如

<!-- no iframe tag anymore -->
<script>
var iframe = document.createElement('iframe');
function loaded() { /* ... */ }
iframe.addEventListener('load', loaded);
document.body.appendChild(iframe);
</script>

但对于这种方法,我们担心通过 JavaScript 创建 iframe 的性能影响 - html iframe 将在脚本开始执行之前渲染和加载。

我们的问题

我们如何可靠地确定跨源 iframe 的内容是否在没有 onload="this.complete = true" 内联处理程序的情况下加载(这需要 CSP 2.0 的 script-src: ...'不安全内联')?

最佳答案

如果没有这些第三方提供商的任何积极合作(例如 postMessage 通信),我认为通过 JS 插入这些 iframe 是唯一现实的选择。或者至少只有在您有机会添加加载处理程序后才“触发”它们加载其实际内容 - 这样您就可以保留 <iframe src="about:blank" data-real-src="http://3rd.party/...">在你的 HTML 中,并在切换之后有一个脚本 src对于 data-real-src添加负载处理程序后。但这些内联脚本将是“渲染阻塞”,因此就整体页面性能而言并不是最好的。

也许您可以通过首先将您自己的域中的最小文档加载到 iframe 中来获得更大的成功,这会做两件事:进入父文档并附加加载事件处理程序,然后将其自身重定向到实际的第三个文档- 之后聚会目标 URL ...?

<iframe id="iframe123" src="/my-iframe-loader.xyz?iframeid=iframe123&
targeturl=http://3rd.party/...">

将 iframe 元素 id 作为 GET 参数传递将允许您直接在父文档中定位相应的 iframe 元素(通过在服务器端动态创建该部分 JS 代码),

parent.document.querySelector('iframe123').addEventlistener(...);
location.href = 'http://3rd.party/...';

此时 iframe 元素应该可以在父文档中访问,因为如果不是这样……我们的 iframe 内的脚本就几乎还没有加载。

这仍然无法消除所有延迟,但我认为这可能比将内联脚本分散在整个父文档中更快(没有渲染阻塞)并且更干净。

(另外,如果您向那些加载器文档添加元刷新,该加载器文档会以很小的延迟重定向到目标 URL,那么您可以实现一个非 JS 后备,至少仍然会加载 iframe 内容...即使适用。)

关于javascript - 没有用于跨源 iframe 的不安全内联注册 onload 处理程序的 CSP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49485788/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com