Skip to content

Unauthenticated file read of files that begin with `index.`

High
louislam published GHSA-5px6-fx2w-459r Jun 4, 2025

Package

uptime-kuma

Affected versions

>= 2.0.0-beta.0, <= 2.0.0-beta.2

Patched versions

2.0.0-beta.3

Description

Summary

The socket message getPushExample is vulnerable to unauthenticated requests, and allows for a path traversal which leads to the leakage of a file that begins with index..

Details

This code is vulnerable to unauthenticated requests, and allows for a path traversal which leads to the leakage of a file that begins with index..

    socket.on("getPushExample", (language, callback) => {

        try {
            let dir = path.join("./extra/push-examples", language);
            let files = fs.readdirSync(dir);

            for (let file of files) {
                if (file.startsWith("index.")) {
                    callback({
                        ok: true,
                        code: fs.readFileSync(path.join(dir, file), "utf8"),
                    });
                    return;
                }
            }
        } catch (e) {

        }

        callback({
            ok: false,
            msg: "Not found",
        });
    });

By using an unauthenticated session, it is possible to request this endpoint as checkLogin(socket); is not called. Furthermore, language could be a path with a path traversal (../) which could read files in other directories.

PoC

By sending the following payload 420["getPushExample","../../"], we can obtain Uptime Kuma's index.html file.
image

This is in BurpSuite, but it can also be accomplished natively in JS.

Steps:

  1. Set a breakpoint in login() to capture the socket object
    image

  2. Call emit with getPushExample and the path. For example: SOCK.emit("getPushExample", '../../', (res) => { console.log(res); });
    image

Impact

This vulnerability has very low impact, as the file must be named index.*. However, as it is a common filename, some sensitive files could be leaked leading to more issues.

The CVSS I calculated was like so: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N

Severity

High

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
None
Availability
None

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

CVE ID

No known CVE

Weaknesses

Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory. Learn more on MITRE.

Missing Authorization

The product does not perform an authorization check when an actor attempts to access a resource or perform an action. Learn more on MITRE.

Credits