
Bitwarden Server v2026.9.2 - Alta - IDOR - inserire elementi di cassaforte decifrabili in collezioni in cui il chiamante non può scrivere
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · bitwarden-cipher-create-acl
Bitwarden Server v2026.9.2 - Bitwarden
La creazione di un cipher di organizzazione sul percorso Entity Framework (MariaDB, Postgres, SQLite) perde l'id del chiamante prima dell'aggancio alla collection. Un membro confermato può inserire un elemento con chiave di organizzazione in una collection su cui non può scrivere. I membri della collection lo sincronizzano come un normale login condiviso.
| ID | nessuna CVE al momento |
| CWE | CWE-863 / CWE-639 |
| CVSS | Alto: 7.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L |
| Prodotto | Bitwarden Server |
| Affetto | v2026.9.2 (9ee4e0eb) lite EF (MariaDB / Postgres / SQLite). MSSQL/Dapper mantiene @UserId. |
| Auth | membro confermato dell'organizzazione |
| Licenza | GNU Affero GPL v3.0 |
| Lab | solo 127.0.0.1 |
L'attaccante aggiunge elementi della cassaforte a una collection condivisa. Non legge né sostituisce i segreti già presenti.
Un membro confermato dell'organizzazione possiede già la chiave dell'organizzazione, quindi il nuovo elemento viene decifrato per tutti coloro che possono vedere quella collection. Bitwarden lo mostra come un normale login, nota, carta o chiave SSH condivisa dall'interno della cassaforte aziendale.
Okta, GitHub, VPN, Payroll) il cui URI punta a un host controllato dall'attaccante. I membri della collection lo aprono da Bitwarden e finiscono sulla pagina dell'attaccante, oppure lo usano con l'auto-compilazione su un sito clone.new AWS key, bastion SSH key, DB password after change). Qualcuno lo copia in produzione o in un terminale.Production può comunque inserire un nuovo elemento al suo interno su lite EF.Se non hanno accesso alla collection di destinazione, POST /api/ciphers/create può restituire 404 dopo che la scrittura è già stata confermata. Le vittime ricevono comunque l'elemento alla sincronizzazione.
Ho fissato bitwarden/server v2026.9.2 (9ee4e0eb) dopo l'ondata del 2026: TDE su richiesta admin (CVE-2026-60104), troncamento di SSO ExternalId (CVE-2026-101878), import di organizzazione con collection vuote (CVE-2026-43638). Questi sono chiusi. L'ACL della collection in fase di creazione no.
CiphersController.PostCreate verifica solo l'appartenenza all'organizzazione, poi passa skipPermissionCheck: true quando OrganizationId è impostato. SaveDetailsAsync considera poi "questa collection esiste nell'organizzazione" come unico controllo sulla collection.
Lite MariaDB/Postgres/SQLite usano EF. CreateAsyncReturnCipher imposta cipher.UserId = null perché è presente un id di organizzazione, poi passa quel null a UpdateCollectionsAsync. Un user id null significa ogni collection dell'organizzazione. SQL Server Dapper mantiene @UserId per Cipher_UpdateCollections (ReadOnly = 0). Quel percorso è il negativo.
Vicoli ciechi già registrati: trattare il cloud POST /organizations come la creazione self-host (è [NotSelfHostedOnly]; lite vuole un file di licenza, quindi il lab inserisce le righe di organizzazione dopo la registrazione); inserire in una collection che il chiamante non può leggere e interpretare l'HTTP 404 come un fallimento (la riga CollectionCipher è già confermata); presumere che MSSQL lite lo mostrerebbe (Dapper non perde l'id del chiamante); lasciare BW_ENABLE_ADMIN disattivato così lite non migra mai User / OrganizationDomain (admin è il migratore EF su questa immagine); omettere Bitwarden-Client-Version su /identity/connect/token e vedere il password grant restituire 400. Una reverse shell. Teatro.
cd lab
./run.sh
Target solo http://127.0.0.1:18160. Immagine ghcr.io/bitwarden/lite:2026.9.2 più MariaDB.
SUCCESS BITWARDEN-CIPHER-CREATE-ACL create-http=404 collectioncipher=1 victim-sync-has-cipher=yes cipher=<id> negative-http=404 readonly-http=200 BITWARDEN-CIPHER-CREATE-ACL-WITNESS
L'inserimento senza accesso restituisce 404 dopo che CollectionCipher è confermato. Sia GET /api/ciphers che /api/sync della vittima contengono il nuovo id. Il read-only su B restituisce 200 e inserisce comunque. Una collection di un'altra organizzazione resta 404 senza riga di join.
Passare l'id dell'utente che salva a EF UpdateCollectionsAsync nello stesso modo in cui CipherDetails_CreateWithCollections passa ancora @UserId dopo aver azzerato la colonna UserId memorizzata. Non trattare un utente null come "tutte le collection" sul percorso di creazione da parte di un membro. L'esistenza nell'organizzazione non è accesso in scrittura.
CiphersController.cs (Post, PostCreate)CipherService.cs (SaveDetailsAsync)CipherRepository.cs (CreateAsyncReturnCipher, UpdateCollectionsAsync)