CVE-2026-59148
@Mockoon/commons-server: Unauthenticated admin API + wildcard CORS allows mock-state hijack and secret theft
Summary
## Summary Mockoon's admin API ([`commons-server/src/libs/server/admin-api.ts`](https://github.com/mockoon/mockoon/blob/4375a8f/packages/commons-server/src/libs/server/admin-api.ts)) is mounted on the same Express listener as the user-defined mock routes, **enabled by default** in every shipped runtime (commons-server, CLI, serverless), serves **`Access-Control-Allow-Origin: *` on every endpoint with all HTTP methods allowed including PUT/POST/PATCH/DELETE/PURGE and `Content-Type` in `Access-Control-Allow-Headers`**, and has **zero authentication of any kind** (no token, no shared secret, no `MOCKOON_ADMIN_TOKEN` env var — searched the repo, returns zero hits). Any unauthenticated caller who can reach the mock server's port (default `0.0.0.0:3000`) can: - Read every `MOCKOON_*` env var used by the operator as secret material in templates (`getEnvVar` helper). - **Write arbitrary process env vars (no prefix check on the WRITE path)** — poison operator's `MOCKOON_API_KEY`, `MOCKOON_JWT_SECRET`, …, or write process-level vars like `AWS_SECRET_ACCESS_KEY` that the surrounding runtime consumes. - **Rewrite every mock route's body / status / headers in-runtime** via `PUT /mockoon-admin/environment` — downstream consumers (frontend dev-server, CI test suite, integration partner) receive attacker-controlled responses and headers including `Set-Cookie`, `Location`, `Content-Security-Policy`, etc. - Read transaction logs / SSE stream (consumer's request bodies + auth headers in clear). - Read/write global template vars; purge state / data buckets / logs. Because of the wildcard CORS reply, the attack **also lands cross-origin from a browser**: a developer who runs `mockoon-cli start ...` locally and visits a malicious website gets their mock state hijacked. --- ## Details ### Root cause `packages/commons-server/src/libs/server/server.ts:127`: ```ts private options: ServerOptions = { ..., enableAdminApi: true, // ← default on }; ``` `packages/cli/src/commands/start.ts:200`: ```ts enableAdminApi: !userFlags['disable-admin-api'], // default true unless --disable-admin-api passed ``` `packages/serverless/src/libs/serverless.ts:21`: ```ts enableAdminApi: true, // ← default on, no flag to disable in the constructor ``` `packages/commons-server/src/libs/server/admin-api.ts:63-74` (permissive CORS on every admin endpoint): ```ts app.use(`${adminApiPrefix}*`, (req, res, next) => { res.setHeaders( new Headers({ 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Origin, Accept, Authorization, Content-Length, X-Requested-With' }) ); next(); }); ``` `packages/commons-server/src/libs/server/admin-api.ts:151-166` (no auth, no prefix check on WRITE): ```ts const setEnvVarHandler = (req, res) => { try { const { key, value } = req.body; if (key !== undefined && value !== undefined) { process.env[key] = value; // ← any process env, any value res.send({ message: `Environment variable '${key}' has been set to '${value}'` }); } else { throw new Error('Key or value missing from request'); } } catch (_error) { res.status(400).send({ message: 'Invalid request' }); } }; ``` `packages/commons-server/src/libs/server/admin-api.ts:373-393` (the most impactful — runtime mock rewrite): ```ts app.put(`${adminApiPrefix}/environment`, (req, res) => { try { const environment: Environment = EnvironmentSchema.validate(req.body).value; if (!environment) { res.status(400).send({ message: 'Invalid environment format' }); return; } updateEnvironment(environment); // ← runtime mutation of every route response res.send({ message: 'Environment updated' }); } catch (_error) { res.status(400).send({ message: 'Invalid environment format' }); } }); ``` Defaul
Affected packages
| Ecosystem | Package | Affected versions | Fixed versions |
|---|---|---|---|
| npm | @mockoon/cli | — | 9.7.0 |
| npm | @mockoon/commons-server | — | 9.7.0 |
Remediation: Upgrade to 9.7.0 or later.
References
Includes data from the GitHub Advisory Database, licensed under CC-BY 4.0.
CVE® is a registered trademark of The MITRE Corporation. CVE content reproduced under the CVE Terms of Use; copyright designation © MITRE.
EPSS scores provided by the FIRST.org Exploit Prediction Scoring System.