
Bitwarden Server v2026.9.2 - Alta - IDOR - insertar elementos de bóveda descifrables en colecciones en las que el llamador no puede escribir
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · bitwarden-cipher-create-acl
Análisis: https://abraxaslabs.tech/research/bitwarden-cipher-create-acl
Bitwarden Server v2026.9.2 - Bitwarden
La creación de cifrados de organización en la ruta de Entity Framework (MariaDB, Postgres, SQLite) descarta el id del llamador antes de adjuntar la colección. Un miembro confirmado puede plantar un elemento con la clave de la organización en una colección en la que no puede escribir. Los miembros de la colección lo sincronizan como un inicio de sesión compartido normal.
| ID | aún sin CVE |
| CWE | CWE-863 / CWE-639 |
| CVSS | Alta: 7.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L |
| Producto | Bitwarden Server |
| Afectado | v2026.9.2 (9ee4e0eb) lite EF (MariaDB / Postgres / SQLite). MSSQL/Dapper conserva @UserId. |
| Autenticación | miembro confirmado de la organización |
| Licencia | GNU Affero GPL v3.0 |
| Laboratorio | solo 127.0.0.1 |
El atacante añade elementos de bóveda a una colección compartida. No lee ni reemplaza los secretos que ya contiene.
Un miembro confirmado de la organización ya posee la clave de la organización, por lo que el nuevo elemento se descifra para todos los que pueden ver esa colección. Bitwarden lo muestra como un inicio de sesión, nota, tarjeta o clave SSH compartido normal desde dentro de la bóveda de la empresa.
Okta, GitHub, VPN, Payroll) cuya URI apunte a un host que controlan. Los miembros de la colección lo abren desde Bitwarden y aterrizan en la página del atacante, o el autocompletado se activa contra un sitio clonado.nueva clave AWS, clave SSH del bastión, contraseña de BD tras el cambio). Alguien lo copia a producción o a una terminal.Production puede aun así colocar un nuevo elemento en ella en lite EF.Si no tienen acceso a la colección objetivo, POST /api/ciphers/create puede devolver 404 después de que la escritura ya se haya confirmado. Las víctimas aun así reciben el elemento en la sincronización.
Fijé bitwarden/server v2026.9.2 (9ee4e0eb) tras la oleada de 2026: TDE de solicitud de administrador (CVE-2026-60104), truncamiento de ExternalId en SSO (CVE-2026-101878), colecciones vacías en la importación de organización (CVE-2026-43638). Esos están cerrados. La ACL de colección en la creación no lo estaba.
CiphersController.PostCreate solo comprueba la membresía en la organización y luego pasa skipPermissionCheck: true cuando OrganizationId está establecido. SaveDetailsAsync trata entonces "esta colección existe en la organización" como la única comprobación de colección.
Lite MariaDB/Postgres/SQLite usan EF. CreateAsyncReturnCipher establece cipher.UserId = null porque hay un id de organización presente, y luego pasa ese null a UpdateCollectionsAsync. Un id de usuario null significa todas las colecciones de la organización. SQL Server Dapper conserva @UserId para Cipher_UpdateCollections (ReadOnly = 0). Esa ruta es la negativa.
Errores de recorrido ya registrados: tratar el POST /organizations en la nube como la creación en self-host (es [NotSelfHostedOnly]; lite requiere un archivo de licencia, por lo que el laboratorio siembra filas de organización después del registro); plantar en una colección que el llamador no puede leer y leer el HTTP 404 como un fallo (la fila CollectionCipher ya está confirmada); asumir que MSSQL lite lo mostraría (Dapper no descarta el id del llamador); dejar BW_ENABLE_ADMIN desactivado para que lite nunca migre User / OrganizationDomain (admin es el migrador de EF en esta imagen); omitir Bitwarden-Client-Version en /identity/connect/token y observar el password grant 400. Una reverse shell. Teatro.
cd lab
./run.sh
Dirígete solo a http://127.0.0.1:18160. Imagen ghcr.io/bitwarden/lite:2026.9.2 más 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
La planta sin acceso devuelve 404 después de que CollectionCipher se confirma. El GET /api/ciphers y /api/sync de la víctima contienen ambos el nuevo id. La lectura en B devuelve 200 y sigue plantando. La colección de organización ajena permanece en 404 sin fila de unión.
Pasar el id del usuario que guarda a UpdateCollectionsAsync de EF de la misma forma en que CipherDetails_CreateWithCollections sigue pasando @UserId después de anular la columna UserId almacenada. No tratar un usuario nulo como "todas las colecciones" en la ruta de creación de miembros. La existencia en la organización no es acceso de escritura.
CiphersController.cs (Post, PostCreate)CipherService.cs (SaveDetailsAsync)CipherRepository.cs (CreateAsyncReturnCipher, UpdateCollectionsAsync)