views:

267

answers:

4

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?

+5  A: 

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.

Tony k
There is a long history of security work on taking languages with unbounded authority and "taming" them to be more safe. See the Joe-E language and the Caja language mentioned above.
Mike Samuel
+1  A: 

No, you practically can't prevent user provided Javascript code to run whatever it wants - even disallowing eval() can't prevent it to run arbitrary programs (it could be a Javascript interpreter itself, in which case it just implements the eval() function, and many other ways - eg. it can add HTML with some event handlers in string form, then execute them, it can document.write() a new script etc.).

If your site doesn't need this user supplied JS to run on other users' computers, I'd just put a big fat warning, add some human control (that could flag rogue code as such), maybe some antivirus software on the server (don't know much about that).

jpalecek
Warnings don't help users make informed decision. They just pass the buck.
Mike Samuel
A: 

Filtering out eval probably doesn't work. I imagine that you could hack round it like this: window['ev' + 'al']('alert("hello world");');. You could of course replace the eval function...

svinto
+5  A: 

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.

bobince