如何在 iframe 中安全地托管第三方 Javascript 代码?

信息安全 xss csrf 框架
2021-08-21 19:46:21

我正在建立一个网站,用户可以在其中添加嵌入内容(YouTube、Google Forms、Airtable ......)并将这些嵌入内容展示给其他人。嵌入是可以包含<script><iframe>-tags 的 HTML 片段。

重要的是嵌入的内容不能接管父页面或使用父站点的会话 cookie 发出请求。

最初看起来很有成效的一个选择是不具有 . 的allow-same-origininsandbox属性<iframe>但是,如果您删除它(例如 YouTube),许多嵌入将不起作用。

正如 WhatWG 建议的那样,CodepenJSBin等网站将此类用户定义的内容托管在不同的域中,以确保 iframe 无法使用来自顶级域的 cookie。但是,它们也包含allow-same-originsandbox-attribute 中,这让我有点困惑。

  • 我需要实施哪些安全措施来安全地托管和显示这些用户定义的嵌入?
  • 除了将代码托管在不同的域上之外,Codepen/JSBin 还实施了哪些其他安全措施来安全地托管和显示用户定义的 HTML?
  • 我可以使用srcdoc-attribute 而不是将嵌入 HTML 托管在不同的域上吗?(接受不支持 IE)

注意:此时 OEmbed、Embedly 和 Iframely 不是我的选择,因为我需要比允许的更多的通用嵌入。

2个回答

如果您嵌入的内容将包含不受信任的脚本,则必须将其加载到来自不受信任域的 iframe 中,或者从未设置标志srcdoc的沙盒 iframe中加载。allow-same-origin

使用该属性嵌入到 iframe 中的内容srcdoc通常被认为与父页面同源,因此以这种方式嵌入不受信任的脚本是不安全的,除非您使用不带标志的属性确保sandbox内容被视为是交叉的-起源。allow-same-origin

相反,通过不受信任的域嵌入 iframe 的内容不会被视为与您的域同源,即使您allow-same-origin在沙盒属性中指定。这是因为allow-same-origin只允许嵌入的内容被视为与它自己的来源同源。它不会授予超出没有沙盒属性的 iframe 所允许的任何额外权限,因此在这种情况下使用它是安全的。WHATWG HTML 规范解释

沙盒原始浏览上下文标志

此标志强制内容进入唯一来源,从而防止它访问来自同一来源的其他内容。

此标志还阻止脚本读取或写入 document.cookie IDL 属性,并阻止对 localStorage 的访问。

这也是为什么大多数嵌入在没有allow-same-origin. 省略该属性会导致嵌入内容将其自己的域视为跨域(例如,嵌入的 YouTube 视频无法与 YouTube 通信,除非通过跨域请求)。

进一步注意,不应该直接从您的主域提供不受信任的内容无论sandbox您在 iframe 上使用什么属性,因为用户可能会被欺骗直接导航到这些页面,绕过沙盒属性。

除了确保不受信任的内容来自与您的主域完全分开的不受信任的域(即最好不是主域的子域)之外,我还建议以下几点:

  • 采取措施确保用户嵌入的内容对于您网站的用户而言是清晰可辨的。如果嵌入内容很容易被误认为是您网站的一部分,则它可能成为网络钓鱼的载体。
  • 如果可行,请考虑使用不受信任域的每个用户唯一子域,以确保来自您网站的一个用户的嵌入内容不会轻易干扰来自另一个用户的嵌入内容。
    • 您可以通过请求将您的不受信任的域添加到公共后缀列表来进一步增强每个用户的隔离。

可能有很多方法可以实现这一点,但我很可能会从服务器端的繁重输入清理开始。

例如:

<iframe width="420" height="315"
src="https://www.youtube.com/watch?v=dQw4w9WgXcQ">
</iframe>

我很可能会编写代码来提取dQw4w9WgXcQ输入的一部分并将其注入到已知良好的模板中。我还要确保视频密钥仅限于数字和字母,因为 YouTube UID 不包含特殊字符。

这很可能适用于 Google 表单和 Airtables。