cloudworker
cloudworker copied to clipboard
inconsistency: disallow `new Function()` eval() loophole
Ajv, the JSON-Schema validator doesn't work on Cloudflare Workers.. It relies on eval()'d code generation, and CF workers don't allow eval().
I was surprised to find that it worked perfectly fine in Cloudworker. I think it's because ajv doesn't actually use eval(), it uses the new Function(<string>) constructor, which we patch into the runtime environment here.
For consistency, we should find a way to disable that mechanism without breaking the foo instanceof Function construct.
Hmm, a naive test shows that new Function() doesn't actually work here. Interesting. EIther AJV started working in contexts that disallow code generation or something else is going on... investigating further.
Minimal repro case:
import Ajv from "ajv";
const handleEvent = () => {
try {
var schema = {
type: "string"
};
var ajv = new Ajv(); // options can be passed, e.g. {allErrors: true}
var validate = ajv.compile(schema);
var valid = validate("foo");
return new Response(`valid: ${valid}`);
} catch (e) {
return new Response(e.stack, { status: 500 });
}
};
addEventListener("fetch", event => {
event.respondWith(handleEvent());
});
I'm building that with parcel build -t browser --no-minify worker.js. It works with Cloudworker, but in CF itself I get
EvalError: Code generation from strings disallowed for this context
at new Function (<anonymous>)
at Ajv.localCompile (worker.js:2946:26)
at Ajv.resolve (worker.js:2015:19)
at Object.resolveRef (worker.js:3015:21)
at Object.generate_ref [as code] (worker.js:3408:22)
at Object.generate_validate [as validate] (worker.js:2615:37)
at Object.generate_properties [as code] (worker.js:5344:26)
at generate_validate (worker.js:2712:35)
at localCompile (worker.js:2914:22)
at Ajv.compile (worker.js:2881:13)
Spooky. How is AJV sneaking past vm.createContext(context, {codeGeneration: {strings: false}})?
Okay, confirmed my original hypothesis - new Function("true"); seems to get around the ban on code generation.
I added a few cases in your PR that should be disallowed. The rule is any evaluation of any generated code is disallowed (wasm is one non obvious case).