Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
bitwarden-cipher-create-acl — Bitwarden Server v2026.9.2 - High - IDOR - plant decryptable vault items into collections the caller cannot write | Kitploit
Tools/GitHubGitHub/abraxas/bitwarden-cipher-create-acl
Authentication & AuthorizationVulnerability AnalysisExploitationWeb Application ExploitationWeb SecurityPenetration TestingLabs & Practice
GitHub

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share
abraxas/bitwarden-cipher-create-acl

bitwarden-cipher-create-acl

Bitwarden Server v2026.9.2 - High - IDOR - plant decryptable vault items into collections the caller cannot write

View Repository
11113 days agoNot yet reviewed

Abraxas Labs - bitwarden-cipher-create-acl

abraxaslabs.tech  ·  github.com/abraxas  ·  @abraxas_null  ·  [email protected]  ·  bitwarden-cipher-create-acl

bitwarden-cipher-create-acl

Bitwarden Server v2026.9.2 - Bitwarden

Org cipher create on the Entity Framework path (MariaDB, Postgres, SQLite) drops the caller id before collection attach. A confirmed member can plant an org-key item into a collection they cannot write. Collection members sync it as a normal shared login.

IDno CVE yet
CWECWE-863 / CWE-639
CVSSHigh: 7.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L
ProductBitwarden Server
Affectedv2026.9.2 (9ee4e0eb) lite EF (MariaDB / Postgres / SQLite). MSSQL/Dapper keeps @UserId.
Authconfirmed org member
LicenseGNU Affero GPL v3.0
Lab127.0.0.1 only

What an attacker can do

The attacker adds vault items to a shared collection. They do not read or replace the secrets already in it.

A confirmed org member already has the org key, so the new item decrypts for everyone who can see that collection. Bitwarden shows it as a normal shared login, note, card, or SSH key from inside the company vault.

  • Phish from the vault. Plant a login named like a real shared item (Okta, GitHub, VPN, Payroll) whose URI points at a host they control. Collection members open it from Bitwarden and land on the attacker page, or auto-fill against a lookalike.
  • Poison ops. Plant a secure note or login that looks like a rotation (new AWS key, bastion SSH key, DB password after change). Someone copies it into production or a terminal.
  • Stay after they are kicked. The create is a new cipher in the collection. It remains for everyone with access after the attacker membership is removed.
  • Bypass read-only. A contractor who may only read Production can still drop a new item into it on lite EF.

If they have no access to the target collection, POST /api/ciphers/create can return 404 after the write is already committed. Victims still get the item on sync.

How I found it

I pinned bitwarden/server v2026.9.2 (9ee4e0eb) after the 2026 wave: admin-request TDE (CVE-2026-60104), SSO ExternalId truncation (CVE-2026-101878), org import empty collections (CVE-2026-43638). Those are closed. Collection ACL on create was not.

CiphersController.PostCreate only checks org membership, then passes skipPermissionCheck: true when OrganizationId is set. SaveDetailsAsync then treats "this collection exists in the org" as the only collection check.

Lite MariaDB/Postgres/SQLite use EF. CreateAsyncReturnCipher sets cipher.UserId = null because an org id is present, then hands that null into UpdateCollectionsAsync. Null user id means every collection in the org. SQL Server Dapper keeps @UserId for Cipher_UpdateCollections (ReadOnly = 0). That path is the negative.

Wrong turns already recorded: treating cloud POST /organizations as the self-host create (it is [NotSelfHostedOnly]; lite wants a license file, so the lab seeds org rows after register); planting into a collection the caller cannot read and reading HTTP 404 as a miss (the CollectionCipher row is already committed); assuming MSSQL lite would show it (Dapper does not drop the caller id); leaving BW_ENABLE_ADMIN off so lite never migrates User / OrganizationDomain (admin is the EF migrator on this image); omitting Bitwarden-Client-Version on /identity/connect/token and watching password grant 400. A reverse shell. Theatre.

Lab

cd lab
./run.sh

Target only http://127.0.0.1:18160. Image ghcr.io/bitwarden/lite:2026.9.2 plus 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

No-access plant returns 404 after CollectionCipher is committed. Victim GET /api/ciphers and /api/sync both contain the new id. Read-only on B returns 200 and still plants. Foreign-org collection stays 404 with no join row.

The fix

Pass the saving user id into EF UpdateCollectionsAsync the same way CipherDetails_CreateWithCollections still passes @UserId after it nulls the stored UserId column. Do not treat a null user as "all collections" on the member create path. Existence in the org is not write access.

References

  • github.com/bitwarden/server tag v2026.9.2
  • CiphersController.cs (Post, PostCreate)
  • CipherService.cs (SaveDetailsAsync)
  • CipherRepository.cs (CreateAsyncReturnCipher, UpdateCollectionsAsync)
  • CWE-863

License

GNU Affero GPL v3.0

Download Tool