允许用户向您的网站添加自己的 JavaScript 的安全问题? [英] Security Issues for allowing users to add own JavaScript to your site?

查看:21
本文介绍了允许用户向您的网站添加自己的 JavaScript 的安全问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我计划创建一个开源教育网络应用,人们可以在其中添加和编辑内容(有点像维基百科).

但是,我希望添加另一个功能,允许用户使用 JavaScript 添加他们自己的交互式内容.(类似于 JSFiddle 的做法)

这样做有什么安全问题?可选问题:如何克服这些问题?

解决方案

是的,您可以使用 HTML5 Sandbox 仅在 IFrame 中加载用户脚本.

您应该只托管来自与主站点不同的域的用户内容.如果攻击者说服用户直接访问页面(在沙箱之外).例如如果您的网站是 www.example.com,您可以使用以下代码来显示沙盒 IFrame(注意 .org 而不是 .com,这是一个完全不同的域):

<iframe src="https://www.example.org/show_user_script.aspx?id=123" sandbox="allow-scripts"></iframe>

这将允许使用脚本,但会阻止 IFrame 之外的表单和导航.请注意,这种方法仍然可能会给用户托管网络钓鱼表单以获取凭据带来风险.您应该确保在用户界面中您的站点和用户内容之间的界限是清晰的.即使我们没有指定 allow-forms,这只会阻止直接提交表单,它不会阻止表单元素和 JavaScript 事件处理程序向外部域发送任何数据.

关于 OWASP 的 HTML5 安全备忘单指南 指出这是目的沙盒:

<块引用>

对不受信任的内容使用 iframe 的沙箱属性

在渲染 IFrame 之前,您应该先测试是否支持沙箱:

<iframe src="/blank.htm" sandbox="allow-scripts" id="foo"></iframe>

var sandboxSupported = "sandbox" in document.createElement("iframe");如果(沙盒支持){document.getElementById('foo').setAttribute('src', 'https://www.example.org/show_user_script.aspx?id=123');}别的{//显示 IFrame 不安全}

如果 sandboxSupportedfalse,动态更改 src 而不是重定向,这样做更安全,因为 iframe 将如果重定向没有及时发生,则不会意外呈现.

作为更简单的替代方案,无需检查是否支持沙箱,您可以使用 srcdoc IFrame 属性生成沙箱内容,确保所有内容都是 HTML 编码的:

例如<html><head></head><body>这可能不安全</body></html>

将呈现为

<iframe srcdoc="&lt;html&gt;&lt;head>&lt;/head&gt;&lt;body>这可能不安全&lt;/body>&lt;/html>"sandbox="allow-scripts"></iframe>

或者你可以构造一个数据 blob 对象,小心地再次进行 HTML 编码:

当然,您也可以从 JSON 数据源设置 unsafeDoc 变量.不建议加载 HTML 文件,因为这与必须来自外部域的问题相同,因为攻击者可以诱使用户直接加载该文件.

另外,请不要试图将用户内容直接写入脚本块.如上所示,只要对用户进行正确的 HTML 编码,数据属性是安全的方法数据,因为它是输出服务器端.

在这些情况下,您可以将 src 保留为 blank.html,因为不支持 srcdoc 的旧浏览器只会加载该 URL.

正如 @Snowburnt 所提到的,没有什么能阻止用户脚本将用户重定向到偷渡式下载 发生,但这种方法,假设用户是最新的补丁,并且不存在零日漏洞,这是一种安全的方法,因为它可以保护其通过同源政策,最终用户及其在您网站上的数据.

I am planning to create an open source education web app where people can add and edit the content (a bit like Wikipedia).

However I wish to add another feature that allows the user to add their own interactive content using JavaScript. (similar how JSFiddle does it)

What are the security concerns in doing this? Optional question: How can these issues be overcome?

解决方案

Yes you could use HTML5 Sandbox to only load user scripts in an IFrame.

You should only host user content from a different domain than your main site. This will prevent any XSS attack if an attacker convinces a user to visit the page directly (outside of the sandbox). e.g. if your site is www.example.com you could use the following code to display the sandboxed IFrame (note .org rather than .com, which is an entirely different domain):

<iframe src="https://www.example.org/show_user_script.aspx?id=123" sandbox="allow-scripts"></iframe>

This will allow scripts, but forms and navigation outside of the IFrame will be prevented. Note that this approach could still risk a user hosting a phishing form to capture credentials. You should make sure that the boundaries between your site and the user content are clear within the user interface. Even though we haven't specified allow-forms, this only prevents a form from being submitted directly, it does not prevent form elements and JavaScript event handlers from sending any data to an external domain.

The HTML5 Security Cheat Sheet guidance on OWASP states this is the purpose of the sandbox:

Use the sandbox attribute of an iframe for untrusted content

You should test whether sandbox is supported first, before rendering the 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
}

It is safer to do it this way by dynamically changing the src rather than redirecting away if sandboxSupported is false because then the iframe will not accidentally be rendered if the redirect doesn't happen in time.

As a simpler alternative, without the need to check whether the sandbox is supported, you can use the srcdoc IFrame attribute to generate the sandboxed content, making sure that all content is HTML encoded:

e.g. <html><head></head><body>This could be unsafe</body></html>

would be rendered as

<iframe srcdoc="&lt;html&gt;&lt;head&gt;&lt;/head&gt;&lt;body&gt;This could be unsafe&lt;/body&gt;&lt;/html&gt;" sandbox="allow-scripts"></iframe>

Or you could construct a data blob object, being careful to HTML encode again:

<body data-userdoc="&lt;html&gt;&lt;head&gt;&lt;/head&gt;&lt;body&gt;This could be unsafe&lt;/body&gt;&lt;/html&gt;">

<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>

Of course you could also set the unsafeDoc variable from a JSON data source. It is not recommended to load an HTML file, as this has the same problem of it having to be from an external domain, as the attacker could just entice the user to load that directly.

Also, please don't be tempted to write user content into a script block directly. As shown above, data attributes is the safe way to do this, as long as correct HTML encoding is carried out on the user data as it is output server-side.

In these cases you can leave src as blank.html as older browsers that do not support srcdoc will simply load that URL.

As @Snowburnt touches upon, there is nothing stopping a user script from redirecting a user to a site where a drive-by download occurs, but this approach, assuming a user is up to date on patches, and there are no zero day vulnerabilities, this is a safe approach because it protects its end users and their data on your site via the same origin policy.

这篇关于允许用户向您的网站添加自己的 JavaScript 的安全问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆