是的,你可以使用HTML5 沙箱 http://msdn.microsoft.com/en-us/hh563496.aspx仅在 IFrame 中加载用户脚本。
您应该只托管来自与主站点不同的域的用户内容。这将防止任何XSS https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)如果攻击者说服用户直接访问页面(在沙箱之外),则进行攻击。例如如果您的网站是www.example.com
您可以使用以下代码来显示沙盒 IFrame(注意 .org 而不是 .com,这是一个完全不同的域):
<iframe src="https://www.example.org/show_user_script.aspx?id=123" sandbox="allow-scripts"></iframe>
这将允许脚本,但 IFrame 外部的表单和导航将被阻止。请注意,这种方法仍然可能会给用户带来风险托管网络钓鱼表单以捕获凭据 https://stackoverflow.com/a/62431584/413180。您应该确保您的网站和用户内容之间的界限在用户界面中清晰可见。即使我们没有指定allow-forms
,这只会阻止直接提交表单,但不会阻止表单元素和 JavaScript 事件处理程序将任何数据发送到外部域。
The OWASP 上的 HTML5 安全备忘单指南 https://www.owasp.org/index.php/HTML5_Security_Cheat_Sheet#Sandboxed_frames声明这是沙箱的目的:
对不受信任的内容使用 iframe 的沙箱属性
在渲染 IFrame 之前,您应该首先测试是否支持沙箱:
<iframe src="/blank.htm" sandbox="allow-scripts" id="foo"></iframe>
var sandboxSupported = "sandbox" in document.createElement("iframe");
if (sandboxSupported) {
document.getElementById('foo').setAttribute('src', 'https://www.example.org/show_user_script.aspx?id=123');
}
else
{
// Not safe to display IFrame
}
通过动态改变来做到这一点更安全src
而不是重定向离开如果sandboxSupported
is false
因为如果重定向没有及时发生,iframe 就不会意外地被渲染。
作为更简单的替代方案,无需检查沙箱是否受支持,您可以使用srcdoc
IFrame 属性生成沙盒内容,确保所有内容都是 HTML 编码的:
e.g.
<html><head></head><body>This could be unsafe</body></html>
将被渲染为
<iframe srcdoc="<html><head></head><body>This could be unsafe</body></html>" sandbox="allow-scripts"></iframe>
或者您可以构造一个数据 blob 对象,再次小心 HTML 编码:
<body data-userdoc="<html><head></head><body>This could be unsafe</body></html>">
<script>
var unsafeDoc = new Blob([document.body.dataset.userdoc], {type: 'text/html'});
var iframe = document.createElement('iframe');
iframe.src = window.URL.createObjectURL(unsafeDoc);
iframe.sandbox = 'allow-scripts';
</script>
当然你也可以设置unsafeDoc
来自 JSON 数据源的变量。不建议加载 HTML 文件,因为这也存在必须来自外部域的相同问题,因为攻击者可能会诱使用户直接加载该文件。
另外,请不要试图将用户内容直接写入脚本块。如上图所示,数据属性 https://stackoverflow.com/a/21432375/413180是执行此操作的安全方法,只要在服务器端输出时对用户数据执行正确的 HTML 编码即可。
在这些情况下你可以离开src
as blank.html
作为不支持的旧浏览器srcdoc
将简单地加载该 URL。
As @斯诺伯恩 https://stackoverflow.com/a/21218981/413180谈到,没有什么可以阻止用户脚本将用户重定向到某个网站,其中路过式下载 http://en.wikipedia.org/wiki/Drive-by_download会发生,但这种方法假设用户是最新的补丁,并且没有zero day http://en.wikipedia.org/wiki/Zero-day_attack漏洞,这是一种安全的方法,因为它通过同源政策 http://en.wikipedia.org/wiki/Same-origin_policy.