high · 7.8CVE-2026-55426Jul 6, 2026

CVE-2026-55426: linuxfabrik-lib OS Command Injection via shell_exec

Shubham Kandhare
Security Engagement Manager, SecureLayer7

Linuxfabrik monitoring plugins pass user-supplied arguments directly into a shell command string, letting a nagios user inject pipe-separated OS commands and escalate to root via sudoers entries.

Packagelinuxfabrik-lib
Ecosystempip
Affected< 5.0.0
Fixed in5.0.0

The problem

The `lib.shell.shell_exec()` function in linuxfabrik-lib (before 5.0.0) assembled external commands by string concatenation and then split on `|` before passing the result to Python's `subprocess` with `shell=True`. Any argument accepted by a plugin, such as `--repo` in `restic-check`, was placed verbatim into that string.

Because many plugins are listed in `/etc/sudoers` so the nagios monitoring user can run them as root, an attacker who controls the nagios user can supply a pipe-embedded payload and execute arbitrary commands as root. CVSS 7.8 (local, high impact, no interaction needed).

Proof of concept

A working proof-of-concept for CVE-2026-55426 in linuxfabrik-lib, with the exact payload below.

bash
nagios@test-vm:/$ sudo /usr/lib64/nagios/plugins/restic-check --repo '|touch /root/nagios-was-here|'

The pre-patch `shell_exec` split its command string on `|` and executed each segment separately, intentionally supporting multi-step pipelines. Passing `|touch /root/nagios-was-here|` as the `--repo` value caused the assembled string `restic --json --repo=|touch /root/nagios-was-here| --password-file= check` to be split into three parts, and the middle part `touch /root/nagios-was-here` was executed as its own command with the privileges of the calling process (root via sudo).

The root cause is CWE-78: user-controlled data was embedded in a shell command string without quoting or escaping, and the `|` split mechanism actively fragmented that string into executable sub-commands.

The fix

Upgrade `linuxfabrik-lib` to 5.0.0. The fix removes `shell=True`, drops the `|` split feature entirely, and requires all callers to pass commands as argv lists (arrays of strings). A new helper `lib.shell.safe_cli_value()` guards positional arguments against option injection.

All plugins in Linuxfabrik Monitoring Plugins were updated to build argv lists (commit 23bb570f4), contained in every release after v5.2.0.

Reported by OoYo0uto.

References: [1][2]

Related research