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 evaled 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
envunless you're ok with untrusted code mutating it.- Solution: make deep copies if necessary.
- Code inside the
withblock 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 theevalfunction 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?