
Bitwarden Server v2026.9.2 - उच्च - IDOR - कॉलर उन संग्रहों में डिक्रिप्ट करने योग्य वॉल्ट आइटम डाल सकता है जिनमें वह लिख नहीं सकता
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · bitwarden-cipher-create-acl
लेख: https://abraxaslabs.tech/research/bitwarden-cipher-create-acl
Bitwarden Server v2026.9.2 - Bitwarden
Entity Framework पथ (MariaDB, Postgres, SQLite) पर org cipher create, collection attach से पहले caller id को हटा देता है। एक पुष्टिकृत सदस्य (confirmed member) एक org-key आइटम को ऐसे collection में रख सकता है जिसमें वे लिख नहीं सकते। Collection के सदस्य इसे एक सामान्य साझा लॉगिन के रूप में सिंक करते हैं।
| ID | अभी तक कोई CVE नहीं |
| CWE | CWE-863 / CWE-639 |
| CVSS | High: 7.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L |
| Product | Bitwarden Server |
| Affected | v2026.9.2 (9ee4e0eb) lite EF (MariaDB / Postgres / SQLite)। MSSQL/Dapper @UserId रखता है। |
| Auth | पुष्टिकृत org सदस्य |
| License | GNU Affero GPL v3.0 |
| Lab | केवल 127.0.0.1 |
हमलावर साझा collection में vault आइटम जोड़ता है। वे उसमें पहले से मौजूद secrets को पढ़ते या बदलते नहीं हैं।
एक पुष्टिकृत org सदस्य के पास पहले से ही org key होती है, इसलिए नया आइटम उन सभी के लिए डिक्रिप्ट होता है जो उस collection को देख सकते हैं। Bitwarden इसे कंपनी vault के अंदर से एक सामान्य साझा लॉगिन, नोट, कार्ड या SSH key के रूप में दिखाता है।
Okta, GitHub, VPN, Payroll) जैसे नाम वाला लॉगिन रखें जिसका URI उनके नियंत्रण वाले होस्ट की ओर इंगित करे। Collection के सदस्य इसे Bitwarden से खोलते हैं और हमलावर के पेज पर पहुँच जाते हैं, या मिलते-जुलते पेज पर ऑटो-फ़िल कर देते हैं।new AWS key, bastion SSH key, DB password after change)। कोई इसे प्रोडक्शन या टर्मिनल में कॉपी कर लेता है।Production पढ़ सकता है, वह भी lite EF पर उसमें नया आइटम डाल सकता है।यदि उनके पास लक्षित collection तक पहुँच नहीं है, तो POST /api/ciphers/create लिखावट पहले ही कमिट हो जाने के बाद 404 लौटा सकता है। पीड़ितों को सिंक पर फिर भी आइटम मिल जाता है।
मैंने 2026 की लहर के बाद bitwarden/server v2026.9.2 (9ee4e0eb) को पिन किया: admin-request TDE (CVE-2026-60104), SSO ExternalId truncation (CVE-2026-101878), org import empty collections (CVE-2026-43638)। वे बंद हैं। create पर collection ACL नहीं था।
CiphersController.PostCreate केवल org सदस्यता जाँचता है, फिर जब OrganizationId सेट हो तो skipPermissionCheck: true पास करता है। इसके बाद SaveDetailsAsync "यह collection org में मौजूद है" को एकमात्र collection जाँच मान लेता है।
Lite MariaDB/Postgres/SQLite EF का उपयोग करते हैं। CreateAsyncReturnCipher cipher.UserId = null सेट करता है क्योंकि org id मौजूद है, फिर उस null को UpdateCollectionsAsync में दे देता है। Null user id का अर्थ है org का हर collection। SQL Server Dapper Cipher_UpdateCollections (ReadOnly = 0) के लिए @UserId रखता है। वह पथ नकारात्मक है।
गलत मोड़ जो पहले ही दर्ज हो चुके हैं: क्लाउड POST /organizations को self-host create मान लेना (यह [NotSelfHostedOnly] है; lite को लाइसेंस फ़ाइल चाहिए, इसलिए लैब register के बाद org पंक्तियाँ seed करता है); ऐसी collection में plant करना जिसे caller पढ़ नहीं सकता और HTTP 404 को miss समझना (CollectionCipher पंक्ति पहले ही commit हो चुकी है); यह मान लेना कि MSSQL lite इसे दिखा देगा (Dapper caller id को drop नहीं करता); BW_ENABLE_ADMIN बंद छोड़ देना जिससे lite कभी User / OrganizationDomain migrate ही नहीं करता (इस image पर admin ही EF migrator है); /identity/connect/token पर Bitwarden-Client-Version छोड़ देना और password grant 400 होते देखना। एक reverse shell। नाटक।
cd lab
./run.sh
केवल http://127.0.0.1:18160 को लक्षित करें। इमेज ghcr.io/bitwarden/lite:2026.9.2 के साथ 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
CollectionCipher कमिट होने के बाद no-access plant 404 लौटाता है। Victim के GET /api/ciphers और /api/sync दोनों में नया id शामिल होता है। B पर read-only 200 लौटाता है और फिर भी plant करता है। Foreign-org collection बिना join row के 404 ही रहता है।
सेव करने वाले user id को EF UpdateCollectionsAsync में उसी तरह पास करें जैसे CipherDetails_CreateWithCollections संग्रहीत UserId कॉलम को null करने के बाद भी @UserId पास करता है। member create path पर null user को "सभी collections" न मानें। org में मौजूद होना write access नहीं है।
CiphersController.cs (Post, PostCreate)CipherService.cs (SaveDetailsAsync)CipherRepository.cs (CreateAsyncReturnCipher, UpdateCollectionsAsync)