It's a well known fact that neither Javascript's eval
keyword nor Function
objects created from strings should ever for any reason be used to run untrusted code.
However, I'm wondering if ES6 proxies change that. Consider:
let env = {eval: eval};
let proxy = new Proxy(env, { has: () => true });
with(proxy) {eval('...')}
The proxy object pretends to have all possible properties, which means that it blocks the search of higher scopes. Within the with
block, any properties not set on env
appear undefined
, and any global properties set inside the with block are actually set on env
.
This seems to allow me to set up a completely controlled and isolated environment for the eval
ed code to run in. What are the risks?
Here are a few concerns I can see:
- Don't put anything that references
window
, ordocument
, orlocalStorage
, or anything else sensitive, intoenv
. - Don't put any mutable object into
env
unless you're ok with untrusted code mutating it.- Solution: make deep copies if necessary.
- Code inside the
with
block has no access to anything outside it. If it needs things likeMath
,Object
, orString
, they have to be put inenv
- which means these can be modified by malicious code. Even theeval
function in my minimal example above can be modified.- Solution: Create proxies for these objects to white-list read-only access to specific properties.
As long as you follow these guidelines, is this actually safe? Are there other concerns?