How can I enable support for `eval()` in Workers?

Yes yes I know all the caveats about eval() but it's essential for my use-case. When running in dev mode (but with --remote i.e. running on CF architecture) I get:
EvalError: Code generation from strings disallowed for this context
EvalError: Code generation from strings disallowed for this context
I've read this but didn't fully understand what to action from it. Could someone please advise? Thank you!
29 Replies
zegevlier
zegevlier5mo ago
You can't enable it. Workers running on Cloudflare's network cannot eval. Perhaps #workers-for-platforms could work for you? If you're fine with the workers running locally, you can enable eval in workers on workerd.
Mitya
Mitya5mo ago
Oh dang... I've spent 3 weeks converting our app to serverless/CF and I'm completely screwed if I can't get eval to work. Could you please elaborate on WfP? I'm unfamiliar with that or how it differs from plain old Workers that I'm currently using. I'm afraid I also don't understand your second paragraph - I'm quite new to the serverless/CF world. Thank you
zegevlier
zegevlier5mo ago
What do you need eval for? WfP is an (mostly enterprise-only, though not entirely) feature that lets you upload workers and call them dynamically. It's intended to be used for letting your users write and upload code that does something on your website. For more info see https://developers.cloudflare.com/cloudflare-for-platforms/workers-for-platforms/
Mitya
Mitya5mo ago
To clarify, it's not literally eval() I'm using but the new Function() constructor which I suppose is eval() via another name (I know there are some scoping differences.) We have a system where users build automations. We have a UI for this and their automations are saved in proprietary (i.e. pseudo) code. I then have a parser that turns this code into valid JS, which is then fed to the func construc. WfP sounds a little nuclear and complex for what we need so it would be great if there were any way around this other than that.
zegevlier
zegevlier5mo ago
There really isn't. If you want the code to run in workers on Cloudflare's network, you can't use eval (or similar). I think WfP would fit quite well with that use-case, but of course the enterprise nature of it makes that a tough pill to swallow. The alternative would be to run the user code somewhere else, or create a worker yourself from the user's code and run that. The latter has major downsides, biggest of which is that the number of workers is limited to 500, which means a maximum of 500 different JS scripts.
Mitya
Mitya5mo ago
Ah dang. Well, I appreciate the advice all the same. I'll have to give it some thought. Would another option be to write a physical JS file that can then be imported and read, rather than evaluating strings of JS?
zegevlier
zegevlier5mo ago
Do have a look at this: https://discord.com/channels/595317990191398933/1012440514135593083/1103682164870103130 It isn't entirely enterprise only, but added on a case-by-case basis That would still require (bundling it and) uploading it to a worker. You can't dynamically write files and import them in the worker itself
Mitya
Mitya5mo ago
Ah OK fair enough. When you say tough pill to swallow, presumably that's re: the higher costs? And would this no-eval limitation be true of serverless in general or just CF Workers, do you suppose?
zegevlier
zegevlier5mo ago
Yea higher costs, especially if you need to get Ent, that starts at several thousands of dollars a month. Hopefully you'll be able to get it on paygo though! And, as you already noted, it will require at least some architectural changes for you. I think it depends on the way the serverless is implemented. A lot of serverless providers give you a full VM that is started when it is requested, which means you can do basically anything you want. Workers are very different, they only spin up a V8 isolate for you, which is much cheaper and faster, but also provides less of a boundary between your code and other people's code (and data). Therefore, workers have a rather strict safety model (https://developers.cloudflare.com/workers/reference/security-model/), which includes making sure all code executed on the platform can be audited by CF employees if you are attacking the platform. Eval doesn't allow this. See https://github.com/cloudflare/workerd/discussions/1432#discussioncomment-7644428
Mitya
Mitya5mo ago
Ah OK that makes sense. Just finally, could I ask you to clarify what you mean by "If you're fine with the workers running locally, you can enable eval in workers on workerd." Does that pertain to WfP, or Workers? Just found this thread which says eval is "available via a binding". Does that have any significance to what I'm trying to do? Really appreciate your help, BTW.
zegevlier
zegevlier5mo ago
Those last two are related: The workers runtime, workerd, can be run locally. That's also what miniflare (which is in turn used by wrangler) uses to run your development workers locally. In the local version of the runtime, you can use eval via that binding, but that would only run on your own server(s), not on Cloudflare's network.
Mitya
Mitya5mo ago
Ahhhh right. Just to clarify: you meant earlier that I wouldn't be able to fp.write a file and then import it within the same runtime?
kian
kian5mo ago
Correct, all files must be bundled at deploy time
zegevlier
zegevlier5mo ago
Yea that, and workers also don't have a file system. There wouldn't even really be a place to write a file to 😅
Mitya
Mitya5mo ago
Given @kian's reply I guess the answer here will be no, but I assume I couldn't use a Node loader to load modules from remote sources? Not eval'd code exactly, but not bundled either...
kian
kian5mo ago
The only way you can really have unbundled code evaluated is running a JS engine in WASM which isn’t ideal eval, new Function, URL imports, WASM from a buffer, etc - none of them will work in Workers
Mitya
Mitya5mo ago
WASM - not sure what this but can check it out but I note that you say it's not ideal, whatever it is!
kian
kian5mo ago
WebAssembly - native languages like C or Rust can compile to it and then you can run that in Workers Of course, without a lot of plumbing, it tends to be pretty basic (you’re not going to be able to access Workers runtime APIs without connecting them all up)
kian
kian5mo ago
Twitter
vxTwitter / fixvx
Kian (@Kian_NH)
Turns out you can use the @boa_engine JavaScript Engine on @Cloudflare Workers This example comes out to 1,224 KiB - which is below the 5 MiB limit of the Workers paid plan! 💖 45 🔁 11
kian
kian5mo ago
I’ve used Boa before but I’m pretty sure someone else got QuickJS or JSC working
kian
kian5mo ago
JSC.js
JSC.js
JavaScriptCore on WebAssembly
kian
kian5mo ago
This works with some hacking to get it working on Workers, Boa Just Works™️
Mitya
Mitya5mo ago
Ah so you can use WASM to run JS, or am I misunderstanding? Anyway I'll go read your links as a starting point - thank you.
kian
kian5mo ago
Kind of - you compile a JavaScript engine, like the very one that Workers is running on (V8, except that probably won't work) and then you can use that. It's a pretty overengineered/overkill eval
Mitya
Mitya5mo ago
Thanks, I'll do some digging Yeah - sounds like using a nuclear bomb to smash a window, but perhaps my only hope.
kian
kian5mo ago
It depends what you're trying to eval fetch, using KV, HTMLRewriter, etc? probably going to be a lot of work just basic/ECMA JS features? fine
Mitya
Mitya5mo ago
I found this as a seemingly simple way to safe-eval JS via WASM, @kian : https://github.com/maple3142/wasm-jseval?tab=readme-ov-file#usage Does it look like that would do the trick? Leo - the pseudo code is our own invention, proprietary code. So there is no emulator. My parser RegExps it to valid JS. Oh it's hacky AF, but it works a treat. Anyway that's kind of academic for my current issue.
kian
kian5mo ago
Depends if it works in Workers Lots of them assume a browser environment and need lots of hacking together to avoid that
Mitya
Mitya5mo ago
Dang. Oh well, at least there's a glimmer of hope, if I can find a WASM JS safe-eval tool like this that supports Node/Workers and a later ES. What specifically would identify one as bring Workers compat, and is the general idea here at least sound? Cool I'll give it a go. Only question then is whether I can adapt the JS to satisfy the ES constraints. Ha, doesn't work - throws an error from deep in the module's source code. Hey ho.