Security Advisories
CVE-2026-44267: The Elo Sandbox Escape and the Risk of Running User Formulas
What the critical @enspirit/elo flaws are, how to tell if your app is affected, and why user-defined and AI-generated expressions deserve to be treated as untrusted code.
This independent write-up is not affiliated with the vendors named. Patch status reflects public advisories on the date shown, so confirm it against your vendor before acting.
CVE-2026-44267 is a critical sandbox escape in Elo, a purely functional expression language for no-code tools, published on npm as @enspirit/elo. It carries a CVSS 3.1 score of 9.8. A string that should only be able to compute a value can instead run arbitrary code in the host JavaScript runtime. It is fixed in version 1.0.1. This is the Elo programming language, not the Elo rating system or Elo touchscreen hardware.
It was published alongside CVE-2026-44266, a code execution flaw in Elo's Ruby backend, also rated 9.8, and CVE-2026-44265, an injection issue in the programmatic AST API, rated 7.4. GitHub's advisories appeared on October 30, 2026, and the CVE records followed on November 3. Proof-of-concept payloads are public. We have found no reports of exploitation in the wild, and the flaws are not in CISA's Known Exploited Vulnerabilities catalog.
Most readers will not have Elo installed. The pattern behind it is far more widespread, and increasingly common in AI-built software: letting users, or a language model, supply a small expression that your server then evaluates. If your product does that with any library, this advisory is worth your time.
/01
How the flaws work
Elo compiles expressions into other languages, including JavaScript, Ruby, Python, and SQL. Its safety depends on the expression language being unable to express anything dangerous. According to the advisory for CVE-2026-44267, the parser accepted constructor as an ordinary identifier, the compiler did not reject it as a property name, and the JavaScript emitter wrote it straight into the output. Property lookups could therefore walk from an ordinary value up to JavaScript's Function constructor, which runs arbitrary code.
On a Node.js server or CI host, that means code execution with whatever access the process has. In a browser, it behaves as cross-site scripting. The fix rejects a set of prototype and reflection property names at compile time.
CVE-2026-44266 is a similar failure in a different target. The Ruby backend placed user text inside Ruby double-quoted strings without escaping the # character, so Ruby interpolation sequences were executed at runtime. The advisory notes that the same source compiled to JavaScript, Python, or SQL is benign, which is a good illustration of how hard these systems are: an escape that is correct for one output language can be missing for another.
/02
Are you affected?
You are exposed if your application uses @enspirit/elo at version 1.0.0 or earlier and any part of an expression can come from someone other than your developers. That includes end users, customers configuring a workflow, data imported from elsewhere, and text produced by a language model. Expressions written only by your own team and committed to your own repository carry much less risk, but you should upgrade anyway.
Each flaw has its own conditions, listed below. Because Elo could arrive as a dependency of another tool, search your lockfile as well as your package.json. Running pnpm why @enspirit/elo or npm ls @enspirit/elo will show whether and why it is installed.
- CVE-2026-44267: untrusted strings reaching defaultFormats.elo.parse() or the CLI with JavaScript emission.
- CVE-2026-44266: untrusted expressions compiled to the Ruby target.
- CVE-2026-44265: applications building Elo AST objects from JSON, plugin output, or other untyped input.
/03
What to do now
Upgrading is simple: move to @enspirit/elo 1.0.1 or later, redeploy, and confirm the new version is what is actually running. What takes more thought is the question of what happened before you upgraded. If untrusted users could submit expressions to a vulnerable version, an upgrade stops future abuse but does not reveal past abuse.
Compiled output also needs attention. If your system compiles an expression once and stores or caches the generated JavaScript or Ruby, upgrading the library will not change artifacts it already produced. Recompile from source after the upgrade, and let the patched compiler reject whatever it now refuses.
- Upgrade to 1.0.1 or later, and make sure the lockfile reflects it in every deployed service.
- Invalidate and regenerate any cached or stored compiled expressions.
- Review saved expressions for references to constructor, prototype, or similar reflection names.
- Rotate any secrets available to the process if untrusted input could have reached a vulnerable version.
- Check logs for unexpected child processes or outbound connections from the service that evaluates expressions.
/04
Why expression sandboxes are so easy to get wrong
Formula fields, custom rules, template languages, and low-code automation are attractive product features. The usual approach is to compile a small language to JavaScript, or to evaluate it inside the host runtime, and block anything dangerous. The trouble is that JavaScript's object model offers many routes to powerful functions, so a filter must be complete while an attacker only needs to find one gap. Note that the patch here is itself a denylist, which is a reasonable fix but not a security boundary you should rely on alone.
A stronger design assumes the language layer will eventually fail and contains the damage. Node's own documentation warns that its vm module is not a security mechanism, so true isolation has to come from something else: a separate process or a dedicated isolate, with no secrets, no ambient network access, and strict limits on time and memory.
- Evaluate untrusted expressions in a separate, low-privilege process or isolate.
- Provide no environment secrets, database credentials, or internal network access to that process.
- Prefer interpreting a parsed AST over generating and executing source code.
- Enforce time and memory limits, since denial of service is also a concern.
- Use an allowlist of operations and properties where you can, not a denylist.
/05
The AI angle: model output is untrusted input
This pattern has become much more common with AI features. A popular way to add natural-language functionality is to have a model turn a request into a filter, a formula, or a piece of code, then execute the result. It feels safe because your own system produced the expression. It is not, because the model's input includes user text and possibly documents and web pages, and any of those can steer what it writes. Output from a language model belongs in the same category as a form field filled in by a stranger.
AI-assisted development can also introduce this risk without anyone choosing it. Ask an assistant to add user-defined rules and it may reach for a small library you have never heard of, or for eval. Either might work in every demo. Neither prompt nor code review will flag it unless someone knows to ask what happens when the input is hostile.
If your product earns revenue and evaluates anything users or models can influence, this is exactly where an experienced engineer is worth paying for. A few hours of review can usually establish where untrusted input reaches an evaluator, and what that process can touch if it escapes. We do this work when we productionize AI-built applications, and through retainers once a product needs someone to keep watching its dependencies. Either way, get the upgrade done today.
Frequently asked
Questions about this topic.
Which Elo versions are affected by CVE-2026-44267?
All versions of @enspirit/elo before 1.0.1 are affected. Version 1.0.1 fixes CVE-2026-44267 as well as CVE-2026-44266 and CVE-2026-44265, according to the project's GitHub advisories.
Is this related to the Elo rating system?
No. This concerns the Elo expression language published as @enspirit/elo, which is used for no-code tools and data transformation. It has nothing to do with chess-style Elo ratings, or with Elo-branded touchscreen products.
Is it safe to execute expressions generated by an LLM?
Only if you treat them as untrusted. Validate them against a strict grammar, run them with limited privileges, and make sure an escape would not expose secrets or internal systems. A model's output can be influenced by the content it reads, so it should not be trusted just because your application generated it.
Sources
- GHSA-33r5-xmm8-v6x5 (CVE-2026-44267), GitHub Advisory Database
- GHSA-7w38-ggh5-v542 (CVE-2026-44266), Elo project
- GHSA-x9rp-7wh3-2rj5 (CVE-2026-44265), Elo project
- CVE-2026-44267 record, CVE Program
- CVE-2026-44267 advisory, GitLab Advisory Database
- CVE-2026-44267 analysis, CVEReports
- VM module documentation, Node.js
- Known Exploited Vulnerabilities catalog, CISA