
Bitwarden Server v2026.9.2 - Alta - IDOR - inserir itens de cofre descriptografáveis em coleções nas quais o chamador não pode escrever
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · bitwarden-cipher-create-acl
Write-up: https://abraxaslabs.tech/research/bitwarden-cipher-create-acl
Bitwarden Server v2026.9.2 - Bitwarden
A criação de cipher de organização no caminho do Entity Framework (MariaDB, Postgres, SQLite) descarta o id do chamador antes da vinculação à coleção. Um membro confirmado pode inserir um item com chave de organização em uma coleção na qual não pode escrever. Os membros da coleção o sincronizam como um login compartilhado normal.
| ID | ainda sem CVE |
| 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 |
| Produto | Bitwarden Server |
| Afetado | v2026.9.2 (9ee4e0eb) lite EF (MariaDB / Postgres / SQLite). MSSQL/Dapper mantém @UserId. |
| Autenticação | membro confirmado da organização |
| Licença | GNU Affero GPL v3.0 |
| Lab | apenas 127.0.0.1 |
O atacante adiciona itens de cofre a uma coleção compartilhada. Ele não lê nem substitui os segredos que já estão nela.
Um membro confirmado da organização já possui a chave da organização, então o novo item é descriptografado por todos que conseguem ver aquela coleção. O Bitwarden o exibe como um login, nota, cartão ou chave SSH compartilhado normal de dentro do cofre da empresa.
Okta, GitHub, VPN, Payroll) cuja URI aponta para um host controlado pelo atacante. Os membros da coleção o abrem pelo Bitwarden e caem na página do atacante, ou o preenchimento automático é feito contra um site parecido.nova chave AWS, chave SSH do bastion, senha do BD após alteração). Alguém copia isso para produção ou para um terminal.Production ainda consegue inserir um novo item nela no lite EF.Se ele não tiver acesso à coleção alvo, POST /api/ciphers/create pode retornar 404 depois que a gravação já foi confirmada. As vítimas ainda recebem o item na sincronização.
Eu fixei bitwarden/server v2026.9.2 (9ee4e0eb) após a onda de 2026: TDE de solicitação de admin (CVE-2026-60104), truncamento de ExternalId de SSO (CVE-2026-101878), coleções vazias na importação de organização (CVE-2026-43638). Esses estão fechados. A ACL de coleção na criação não estava.
CiphersController.PostCreate apenas verifica a associação à organização e então passa skipPermissionCheck: true quando OrganizationId está definido. SaveDetailsAsync então trata "esta coleção existe na organização" como a única verificação de coleção.
Lite MariaDB/Postgres/SQLite usam EF. CreateAsyncReturnCipher define cipher.UserId = null porque um id de organização está presente, e então passa esse null para UpdateCollectionsAsync. User id nulo significa todas as coleções da organização. SQL Server Dapper mantém @UserId para Cipher_UpdateCollections (ReadOnly = 0). Esse caminho é o negativo.
Erros já registrados: tratar o POST /organizations na nuvem como a criação no self-host (ele é [NotSelfHostedOnly]; o lite exige um arquivo de licença, então o laboratório semeia linhas de organização após o registro); inserir em uma coleção que o chamador não consegue ler e interpretar o HTTP 404 como ausência (a linha CollectionCipher já está confirmada); assumir que o MSSQL lite o mostraria (o Dapper não descarta o id do chamador); deixar BW_ENABLE_ADMIN desativado para que o lite nunca migre User / OrganizationDomain (o admin é o migrador EF nesta imagem); omitir Bitwarden-Client-Version em /identity/connect/token e observar o password grant retornar 400. Um reverse shell. Teatro.
cd lab
./run.sh
Aponte apenas para http://127.0.0.1:18160. Imagem ghcr.io/bitwarden/lite:2026.9.2 mais 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
Planta sem acesso retorna 404 após CollectionCipher ser confirmado. GET /api/ciphers e /api/sync da vítima contêm ambos o novo id. Somente leitura em B retorna 200 e ainda planta. Coleção de organização externa permanece 404 sem linha de associação.
Passe o id do usuário que salva para o UpdateCollectionsAsync do EF da mesma forma que CipherDetails_CreateWithCollections ainda passa @UserId depois de anular a coluna UserId armazenada. Não trate um usuário nulo como "todas as coleções" no caminho de criação de membro. Existência na organização não é permissão de escrita.
CiphersController.cs (Post, PostCreate)CipherService.cs (SaveDetailsAsync)CipherRepository.cs (CreateAsyncReturnCipher, UpdateCollectionsAsync)