最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Security Issues for allowing users to add own JavaScript to your site? - Stack Overflow

programmeradmin2浏览0评论

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

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

Share Improve this question asked Jan 19, 2014 at 15:43 Yahya UddinYahya Uddin 29k40 gold badges157 silver badges247 bronze badges 3
  • Do you mean "own interactive" - where every user does only execute scripts installed by himself or "interactive content" where any user can upload code that will be executed by others? – Bergi Commented Jan 19, 2014 at 17:44
  • where user can upload code that will be executed by others – Yahya Uddin Commented Jan 19, 2014 at 21:50
  • This is dangerous. Avoid it if you can (e.g. by only allowing them to configure given modules); if you need/want it you should use some peer-review process so that malign code is rejected. – Bergi Commented Jan 19, 2014 at 22:19
Add a ment  | 

2 Answers 2

Reset to default 9

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. you could use the following code to display the sandboxed IFrame (note rather than ., which is an entirely different domain):

<iframe src="https://www.example/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/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 remended 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.

One big issue is cross-site scripting where users add code that tells the browser to open and run code from other sites. Say they add something that creates an iFrame or a hidden iFrame pointing to a site and starts downloading malicious code.

There's no simple way around it (thanks to Bergi in the ments) to make sure no elements are created and no ajax calls are made.

I've been a member of sites that provided this functionality, but for those sites I paid for my own space so any vulnerabilities I add are inconveniencing my own clients, in that case it's a little more okay to let that slip by since it's not a security leak for everyone.

One way around this is to create customizable controls for the users to use to add interactivity. The plus is that you control the javascript being added, the minus is that your user base will have to request and then wait for you to create them.

发布评论

评论列表(0)

  1. 暂无评论