A Case for Safe Eval
github.com
github.com
This use case doesn't seem to me to be one that's likely to arise often.
Not really, I can write
((/**/)=>5)(/**/)
Using eval on data that are provided by a user is always a bad idea. You cannot be sure that your sanitiser will be safe with new syntax elements. '((/**/) => 5)(/**/)'.replace(/(\(\s*\)|[^0-9.()+\-*\/><=!&|?:])+/g, '')
> "((/**/)=>5)(/**/)"
((/**/)=>5)(/**/)
> 5
Yup, this does indeed work.I don't see a way to exploit it, but that means very little (as shown by the fact that the author missed this one).
Removing characters you know to be illegal and then trying to run it anyway is asking for trouble. If it contains illegal characters, it should fail immediately.
True. Most bugs with security impact seem to happen in the input handling layer, where user input is parsed into data structures. One of the most fundamental problems in today's networked world is how software must be able to safely communicate with virtually any other computer in the world. Servers are configured to indiscriminately accept connections from anyone who tries to connect; no concept of trust is involved.
Counterpoint: good luck getting that magical regex to scale to many new operators. Or other data types, for that matter. What if, for instance, you wanted to add support for strings? Suddenly, the entire original approach is useless and building a tiny compiler is the best and safest option.
It also the case that, as olegbulatov demonstrated, you're fighting an uphill battle trying to sanitize code with a regex. There's really not reasonable way to prove with 100% certainty that a regexp blocks _all possible expressions_ that could do nasty things. Writing a tiny compiler might be a pain in the ass, but you can be very sure of the safety that it offers....and it doesn't need to use eval().
You're trying to get the evil out of the string, at which point the remainder of the string is good. That's not how strings work. If it happens to work now, who knows what syntax will show up next year (and there are plenty of examples on this page of working around the regex). You're in a constant battle of figuring out whether bytes are good or evil when the actually answer is they're neither.
Full recognition before processing! http://langsec.org/occupy/
Edit: I should add that the crux of the technique involves a two-argument eval() with an explicit environment, as opposed to the single-argument eval() of ECMAScript.
https://en.wikipedia.org/wiki/JSFuck https://stackoverflow.com/questions/2669690/why-does-google-...
Try the converter at http://www.jsfuck.com/ -- or browse the esolang entry: https://esolangs.org/wiki/JSFuck
Spoiler: it can do everything normal JS can. Just because it uses 20,000 characters to do a simple if statement doesn't mean your eval is 'safe'.
Note however that the threat model here does not include denial of service. You have to address that at another level like OS processes or E vats.
Far better would be a capability-based sandbox API in the browser (like the Node.JS one: https://nodejs.org/api/vm.html#vm_vm_createcontext_sandbox_o...) that also supports filters like "stack depth" to limit infinite recursion, and/or some sort of opcount to limit other nonterminating functions. Combine those two things, and you have at least a way to secure arbitrary code you want to eval.
I think that most people with a real/non-insane need for such a service would be willing to pay a fair amount of performance (e.g. introducing an Erlang-esque reduction count idea to code inside the sandbox) to get it working safely.
Mind you, even if that existed it'd be hard to use correctly; people would try to safe-eval code, fail, and open up over-promiscuous capabilities (just like redis: http://antirez.com/news/118), putting us back at square one. For many purposes, though, it would be a very interesting and powerful tool when wielded carefully.
> A Case for Safe Eval
The author's argument is that there is at least one valid use case for eval, not that it belongs in all web projects.
But what is preventing me from doing “((a) => 5)(0)” since the regex only requires at least one non space char between parens...
Or any function call really?
((//)=>5)(//)
*plenty of asterisks*
/**/
Also simplifies ascii art since it's mono-spaced: |\__/,| (`\
_.|o o |_ ) )
---(((---(((---------Provide a $10 prize for setting a cookie to value xyz, or for calling function zyx().
Repeat until safe.. (Makes me think how bug bounties really are useful but not that useful for security).
Infinite loops etc could still happen but they would not significantly effect your page and the worker gets killed when the user navigates.
As far as their regex goes I’m not sure it actually prevents the wonders of [] based programming.
There's an example of using this for untrusted eval in the linked HTML5Rocks post: https://www.html5rocks.com/en/tutorials/security/sandboxed-i... The amount of code involved is pretty minimal and doesn't involve opaque regexes, so something like that is probably the actual best option for someone who wants safe eval.
That StackOverflow user also has their own library that does this using a sandboxed iframe and a web worker: https://github.com/asvd/jailed