
Bitwarden Server v2026.9.2 — высокий уровень — IDOR — внедрение расшифровываемых элементов хранилища в коллекции, в которые вызывающий не может записывать
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · bitwarden-cipher-create-acl
Bitwarden Server v2026.9.2 — Bitwarden
Создание org-шифра на пути Entity Framework (MariaDB, Postgres, SQLite) отбрасывает идентификатор вызывающего до привязки к коллекции. Подтверждённый участник может поместить элемент с org-ключом в коллекцию, в которую он не имеет права записи. Участники коллекции синхронизируют его как обычный общий логин.
| 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 |
| Продукт | Bitwarden Server |
| Затронуто | v2026.9.2 (9ee4e0eb) lite EF (MariaDB / Postgres / SQLite). MSSQL/Dapper сохраняет @UserId. |
| Аутентификация | подтверждённый участник org |
| Лицензия | GNU Affero GPL v3.0 |
| Лаборатория | только 127.0.0.1 |
Атакующий добавляет элементы хранилища в общую коллекцию. Он не читает и не заменяет секреты, уже находящиеся в ней.
Подтверждённый участник org уже имеет org-ключ, поэтому новый элемент расшифровывается для всех, кто видит эту коллекцию. Bitwarden показывает его как обычный общий логин, заметку, карту или SSH-ключ из корпоративного хранилища.
Okta, GitHub, VPN, Payroll), чей URI указывает на контролируемый вами хост. Участники коллекции открывают его из Bitwarden и попадают на страницу атакующего или используют автозаполнение на похожем сайте.new AWS key, bastion SSH key, DB password after change). Кто-то скопирует его в продакшен или терминал.Production, всё равно может поместить новый элемент в неё на lite EF.Если у них нет доступа к целевой коллекции, POST /api/ciphers/create может вернуть 404 после того, как запись уже зафиксирована. Жертвы всё равно получают элемент при синхронизации.
Я зафиксировал bitwarden/server v2026.9.2 (9ee4e0eb) после волны 2026 года: admin-request TDE (CVE-2026-60104), усечение SSO ExternalId (CVE-2026-101878), пустые коллекции при импорте org (CVE-2026-43638). Они закрыты. ACL коллекции при создании — нет.
CiphersController.PostCreate проверяет только членство в org, затем передаёт skipPermissionCheck: true, когда задан OrganizationId. SaveDetailsAsync затем считает «эта коллекция существует в org» единственной проверкой коллекции.
Lite MariaDB/Postgres/SQLite используют EF. CreateAsyncReturnCipher устанавливает cipher.UserId = null, потому что присутствует org id, затем передаёт этот null в UpdateCollectionsAsync. Null user id означает все коллекции в org. SQL Server Dapper сохраняет @UserId для Cipher_UpdateCollections (ReadOnly = 0). Этот путь — отрицательный.
Уже зафиксированные ошибочные повороты: трактовка облачного POST /organizations как self-host создания (это [NotSelfHostedOnly]; lite требует файл лицензии, поэтому лаборатория создаёт строки org после регистрации); помещение в коллекцию, которую вызывающий не может читать, и трактовка HTTP 404 как промаха (строка CollectionCipher уже зафиксирована); предположение, что MSSQL lite это покажет (Dapper не отбрасывает идентификатор вызывающего); отключённый BW_ENABLE_ADMIN, из-за чего lite никогда не мигрирует User / OrganizationDomain (admin — это EF-мигратор в этом образе); пропуск Bitwarden-Client-Version на /identity/connect/token и наблюдение 400 при password grant. Обратная оболочка. Театр.
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
Помещение без доступа возвращает 404 после фиксации CollectionCipher. У жертвы GET /api/ciphers и /api/sync оба содержат новый id. Read-only на B возвращает 200 и всё равно помещает. Коллекция чужой org остаётся 404 без строки join.
Передавайте id сохраняющего пользователя в EF UpdateCollectionsAsync так же, как CipherDetails_CreateWithCollections всё ещё передаёт @UserId после обнуления хранимого столбца UserId. Не трактуйте null user как «все коллекции» на пути создания участником. Существование в org — это не право записи.
CiphersController.cs (Post, PostCreate)CipherService.cs (SaveDetailsAsync)CipherRepository.cs (CreateAsyncReturnCipher, UpdateCollectionsAsync)