0

I need to use eval() for a JavaScript-based web app I'm building.

The reason for this is that I want to let people write their own functions that get stored as text, and can be re-used on the site when then need to use them another time. Think along the lines of jsFiddle.

The code will either be run and eval'ed, or will inserted as a script tag. Either way, it leaves the site open to JavaScript injection by malicious users. As such, I'm planning to either filter submitted code, or when a user loads another user's script, have a warning message that the user should first read / check the script before continuing.

So far, I'm looking to filter / warn on the following keywords:

eval
execScript

script

window.*
setInterval
setTimeout
alert
confirm
prompt

document.*
write
innerHTML
insertAdjacentHTML
createElement
appendChild
setAttribute

form.*
submit

XMLHttpRequest

jQuery.*
ajax

base64encode
base64decode

I've not started testing yet, so these are only my initial thoughts.

Anyone got experience or opinion on this?

Thanks, Dave

Dave Stewart
  • 2,324
  • 2
  • 22
  • 24
  • 1
    I don't think jsfiddle uses `eval`. – canon Oct 02 '12 at 22:30
  • 3
    Filtering submitted code would be pointless. People will find their way around a blacklist. What do you plan to do if someone uses "eval" in a string literal? How will you determine which strings are used as output, and which are used to circumvent your sandbox? – cdhowie Oct 02 '12 at 22:31
  • 3
    Bad things bout to happen here. – PeeHaa Oct 02 '12 at 22:31
  • Letting users run custom Javascript is a **Bad Idea**. Filtering can be easily overcome. – Vivin Paliath Oct 02 '12 at 22:32
  • This, sir, is a terrible idea. Think about this for a second - `self[['a', 'lert'].join('')] ("BOO");` - I just got around your filter. And I can continue doing so as long as I can see your code, which of course since it's JS I can.. – Stephen Oct 02 '12 at 22:32
  • I know this doesn't address your problem, but: Avoid to use eval, use: var f = new Function("your function code"); f(); – Alcides Queiroz Oct 02 '12 at 22:33
  • 3
    @alcidesqueiroz How does that solve anything? – cdhowie Oct 02 '12 at 22:33
  • @cdhowie I agree, I'm not giving a solution, but a tip. Eval isn't a good practice. – Alcides Queiroz Oct 02 '12 at 22:35
  • @cdhowie: AFAIK `new Function` creates a new scope and doesn't have access to the local variables of the current scope while `eval` does, so `new Function` seems more "secure". – elclanrs Oct 02 '12 at 22:36
  • @alcidesqueiroz: Good example, you just found the first hole in his blacklist - he only prevents `eval` – Bergi Oct 02 '12 at 22:36
  • @elclanrs So? It would still have access to the `window` global. `new Function()` would only hide the current scope, but this assumes that the things in the current scope are the real problem. (Hint: they're not.) – cdhowie Oct 02 '12 at 22:38
  • Well, thanks loads everyone for the comments; I've certainly got some directions to explore. – Dave Stewart Oct 02 '12 at 22:46

2 Answers2

8

There is no way to make this safe - the characters []()+!{} can be used to construct any arbitrary Javascript code.

http://patriciopalladino.com/blog/2012/08/09/non-alphanumeric-javascript.html

As far as I am aware, jsFiddle works by running user-generated code within an iframe on another domain. It does not use input filtering.

5

Pretty much any filtering can be got around by doing this. You're going to have to sandbox the Javascript. Possible approaches include:

Vivin Paliath
  • 94,126
  • 40
  • 223
  • 295
  • 1
    There's a bunch of great replies on this post about sandboxing JavaScript. http://stackoverflow.com/questions/195149/is-it-possible-to-sandbox-javascript-running-in-the-browser Thanks, you tipped me off to it :) – Dave Stewart Oct 02 '12 at 22:52