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