SharedArrayBuffer in an Iframe



所以SharedArrayBuffer最近被限制为跨源隔离页面作为安全修复。

我们有一个依赖于SharedArrayBuffer的工具,我重新设计了它,使再次工作通过将其移动到一个除去所有其他网站UI的barebones页面,并发送以下标题:

Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin

尝试在成熟站点的iframe中加载它给我控制台错误SharedArrayBuffer will require cross-origin isolation as of M92,然后是ReferenceError: SharedArrayBuffer is not defined-与我在最小页面本身上交叉原点隔离工具之前得到的相同。

我试图包含iframe的页面是而不是跨源隔离。这样做即使不是不可能,也是非常困难的。我根本不需要与父页面的iframe对话,这只是一个方便/风格的事情。目前的解决方案是在新窗口中将用户链接到最小的跨原点工具页面,但这相当尴尬。

我希望的是,有一些iframe沙盒属性的组合或一些东西,将使这个工作?我为此争论了几个小时。

据我所知,这可能不可行。

尝试在iframe的sandbox属性中添加allow-scriptsallow-same-origin标记:

<iframe src="…" sandbox="allow-scripts allow-same-origin"></iframe>
^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^

以下是关于这个主题的一些相关资源:

  • 沙箱,IFrame和allow-same-origin (StackOverflow问题)
  • 通过sandbox属性保护iframe
  • <iframe>:内联框架元素(MDN文档),-不要错过注意

先试试上面的,如果它对你的SharedArrayBuffer问题没有帮助,那么事情就有点复杂了。

正确的跨源需要子资源的显式头(<iframe>必须发送头),当子资源是第三方且失控时,这是一个大问题。为了缓解这个问题,有一个提案Cross-Origin-Embedder-Policy: credentialles

然而,有一个问题:它不会改变<iframe>的工作方式(遗憾的是,这正是需要的!)。有一个关于匿名iframe的讨论,这将解决这个问题,但它还没有解决,所以我不会屏住呼吸在这里。

所以,剩下的唯一选择是延迟Chrome行为的变化(可以在Chrome 103之前完成):

  1. 请求原点令牌
  2. 将令牌添加到页面中。有两种方法:
    • 在每个页面的头部添加一个<meta>标签。例如,这可能看起来像:<meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
    • 如果你可以配置你的服务器,你也可以使用Origin-TrialHTTP头添加令牌。结果的响应头应该看起来像:Origin-Trial: TOKEN_GOES_HERE

我不确定这个选项是否适合您的情况,但也许它可以帮助您找到一个完整的解决方案。这篇博文描述了在ServiceWorker中通过头部修改来启用SharedArrayBuffer。它的工作顺序如下:

  1. 当页面第一次加载时,一个Service worker被注册
  2. 页面重新加载
  3. SharedArrayBuffer变得可用,因为ServiceWorker控制所有请求的所有CORS头

Service Worker通过添加CORS/COEP头来修改所有请求(该示例取自上述blogpost):

self.addEventListener("install", function() {
self.skipWaiting();
});
self.addEventListener("activate", (event) => {
event.waitUntil(self.clients.claim());
});
self.addEventListener("fetch", function(event) {
if (event.request.cache === "only-if-cached" && event.request.mode !== "same-origin") {
return;
}
event.respondWith(
fetch(event.request)
.then(function(response) {
// It seems like we only need to set the headers for index.html
// If you want to be on the safe side, comment this out
// if (!response.url.includes("index.html")) return response;
const newHeaders = new Headers(response.headers);
newHeaders.set("Cross-Origin-Embedder-Policy", "require-corp");
newHeaders.set("Cross-Origin-Opener-Policy", "same-origin");
const moddedResponse = new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: newHeaders,
});
return moddedResponse;
})
.catch(function(e) {
console.error(e);
})
);
});

相关内容

  • 没有找到相关文章

最新更新