ENDOR-VUL-2026-16041
Server-Side RCE via SES Compartment Escape in variables:resolve
01Record
| Project | NocoBase |
|---|---|
| Component | @nocobase/plugin-flow-engine |
| CWE | CWE-94 |
| CVSS | 9.9 |
| Disclosed | 2026-08-08 |
| Endor reference | ENDOR-VUL-2026-16041 |
| Writeup | Link |
02Detail
Description: NocoBase evaluates user-supplied template expressions inside an SES Compartment to resolve {{ }} placeholders in workflow config. Four defects compound into a full escape, and every one of them is a real defense that does not hold:
- The ACL grants
variables:resolveto anyloggedInuser, which includes the lowest-privilege member role. preprocessExpression()rewrites only literalctx.andctx[tokens throughindexOf, so passingctxinto an arrow function parameter and aliasing it renders the rewriter blind.HttpRequestContextstores the raw Koa context in a TypeScriptprivatefield.privateis a compile-time fiction that compiles to an ordinary instance property, so theReflect.hascheck in the Proxy trap returns true for exactly the field the Proxy was built to hide.- The SES
lockdown()call that would harden intrinsics is commented out behind a// TODO.
The result is arbitrary SQL through sequelize.query() from a single authenticated POST, returning the users table with password hashes in the response body. On PostgreSQL with a superuser database role, COPY … TO PROGRAM runs a shell command on the database host, which is the scope change from application database read to OS execution that carries the score to 9.9. Affects NocoBase through 2.0.38.
Impact: Authenticated SQL Injection escalating to Code Execution on the database host, from the lowest-privileged user in a single request.
The chain is closed in the shipped code. GitHub Security Advisory GHSA-42wx-r3jw-6c5h was assigned and is still in draft as of 2026-08-24, so there is no advisory page to cite. This record will be re-keyed to the advisory when it publishes. Full analysis is in the technical whitepaper.
Discovered by Peyton Kennedy (p80n).