如何在沙盒化的 iframe 中只允许白名单资源(脚本、像素等)运行?

16

我正在寻找一种方法,允许仅在受限制的iframe中运行经过白名单认证的脚本。我考虑使用一个iframe-sandbox指令,该指令只允许在iframe中运行经过白名单认证的脚本。类比于内容安全策略中的script-src指令。

问题:

<iframe sandbox="allow-same-origin allow-scripts" src="https://app.thirdparty.com" width="100%" height="800" frameBorder="0"></iframe>

我网站中的iframe应用程序提供了有价值的功能。然而,它会引入我想要控制(即阻止)的外部资源,例如AnalyticsJavaScript.com和TrackingPixel.com。我希望允许来自app.thirdparty.com的脚本,但是阻止AnalyticsJavaScript.com和TrackingPixel.com。

非常感谢任何帮助。


W3C的Webappsec小组正在研究编辑草案内容安全策略:嵌入式执行(https://w3c.github.io/webappsec-csp/embedded/#allow-csp-from-header)。目前还不是正式推荐。 - rvaneijk
CSP:EE是一个功能,已经在Chrome 61和Opera 48中发布!然而,该功能在W3C规范方面仍处于“编辑草案”阶段,并且没有其他浏览器实现该功能的公共信号。 - Austen Holland
2个回答

6
很不幸,这个问题的答案比较复杂。随着iframe沙盒化的出现,这个问题似乎变得简单了,但你寻找的规范仍然是一个正在进行中的工作。因此,如果你想要良好的浏览器支持,这个问题就变成了如何修改iframe的内容,通常需要使用某种代理方式。
内容安全策略
你真正需要的规范是CSP。在最简单的情况下,你可以允许具有csp="..."属性的特定脚本来访问iframe。
<iframe ...
        src=""
        csp="script-src https://app.thirdparty.com/"
        ...></iframe>

任何来自未指定域名的脚本(例如问题中的跟踪脚本)都不会被允许在响应中。请注意,将脚本限制为特定来源的操作需要与第三方应用程序的服务器进行合作。如果服务器没有告知用户代理它将遵守CSP限制,则响应将被阻止。

CSP仍然是一份草案,可能会在未来发生变化。如评论所述,Chrome 61和Opera 48 已经实现了CSP规范,但目前尚无迹象表明Firefox、Edge或Safari也会实现它。除非您能保证您的用户只使用支持该规范的浏览器,否则跟踪脚本仍将存在于很大一部分用户中。

其余的建议都涉及修改iframe的内容以删除有问题的脚本。

反向代理

创建一个反向代理来阻止iframe中的一些跟踪脚本,可能相当于使用核弹头点燃篝火一样过度杀伤力。但是,如果您能够配置到这种程度,它是我找到的最可靠和无缝的iframe内容注入/修改/阻止方法。 维基百科页面指出:
反向代理是一种代理服务器类型,它代表客户端从一个或多个服务器检索资源。然后将这些资源返回给客户端,看起来就像它们来自代理服务器本身。
由于反向代理是第三方应用程序和您的站点之间的中介,因此它可以透明地修改响应以删除不需要的脚本。在本例中,我将使用Apache,但您的实现实际上取决于您已经使用的服务器。
您需要一个子域名用于代理,指向您的服务器IP地址,例如proxywebapp.yourdomain.com。在您的服务器上,您需要在httpd.conf中创建一个虚拟主机,使用Apache的mod_proxy模块。在您的虚拟主机配置中,您需要将对AnalyticsJavaScript.com和TrackingPixel.com的脚本调用替换为空白。如果第三方应用程序必须使用HTTPS,则反向代理会变得更加棘手,因为您需要为代理的FQDN获取SSL虚拟主机和SSL证书。
<VirtualHost *:*>
    ServerName        proxywebapp.yourdomain.com
    ProxyPreserveHost On
    ProxyPass         "/" "http://app.thirdparty.com/"
    ProxyPassReverse  "/" "http://app.thirdparty.com"

    # in case any URLs have the original domain hard coded
    Substitute        "s|app.thirdparty.com/|proxywebapp.yourdomain.com/|i"
    # replace the undesired scripts with blanks
    Substitute        "s|AnalyticsJavaScript/| /|i"
    Substitute        "s|TrackingPixel/| /|i"
</VirtualHost>

您的 iframe 将指向 proxywebapp.yourdomain.com
<iframe ... src="proxywebapp.yourdomain.com" ...></iframe>

再次强调:这样做可能有些过度,但应该可以透明地实现。

代理脚本

第三个要考虑的选项是在您的服务器上实现一个代理脚本,位于 iframe 和第三方应用程序之间。您将在代理脚本中添加功能,以搜索并删除未经许可的脚本,使其不会到达 iframe。此外,代理意味着 iframe 的内容将验证同源策略,因此您可以在前端使用 JavaScript 删除不需要的内容,尽管这可能不能保证在删除之前脚本不会运行。有许多代理脚本在线提供,适用于各种后端(PHP、Node.js 等等)。您可能会安装脚本,并将其作为 iframe 的 src 添加,例如:<iframe ... src="proxy.php?https://app.thirdparty.com/" ...>

除非针对所有情况正确配置,否则代理可能无法正确传输第三方应用程序和其父服务器之间的数据。需要进行测试。

为了从 iframe 中删除一些脚本而编写自己的服务器端代理可能有些过度。

如果您无法访问后端,则可以使用JavaScript和CORS或JSONP Web应用程序来爬取Web应用程序的内容,并修改它以删除脚本。基本上是在JavaScript中创建自己的代理。这些Web应用程序(Any Origin,All Origins等)允许您绕过跨域策略限制,但由于它们是第三方,您不能再假定任何Web应用程序的数据是私有的。正确传递应用程序与其父服务器之间的任何数据传输的问题仍将存在。
概要
目前,广泛支持的纯前端解决方案不可行。但是,有很多方法可以修改iframe的内容,而不受跨域限制的影响。
内容安全策略看起来很有前途,正是您所要求的,但目前缺乏广泛支持,意味着它只能在非常专业的情况下使用。修改内容的反向代理可能需要大量配置,在这种情况下就像在Hot Wheels轨道上驾驶大型半挂车,但可能会无缝运行。从前向代理进行内容修改有点简单易行,但可能会破坏与第三方应用程序的父服务器之间的通信。

0

目前你无法按照你想要的方式进行操作。正如评论中提到的,CSP:EE是一个尚未出现的东西。

但是你可以尝试代理请求并在服务器端或客户端上删除不必要的脚本,例如:

1)通过XMLHTTPRequest获取所需页面

2)删除不需要的内容

3)将其注入页面上的iframe中

此方法的“可行性”纯粹取决于外部应用程序的功能。即如果前述应用程序需要用户注册/授权才能工作,则它将无法工作,但对于某些简单情况仍然适用。

P.S.:你可以通过浏览器扩展实现解决方案,但我相信这不是你想要的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接