CVE-2026-73974
linuxfabrik-lib: Arbitrary root file read via live --test argument (lib.lftest) across sudoers-whitelisted plugins (LPE)
linuxfabrik-lib provides Python modules for database access, caching, shell execution, and API integrations, and Linuxfabrik Monitoring Plugins uses its shared testing helper across check plugins. Prior to linuxfabrik-lib 6.1.0 and Linuxfabrik Monitoring Plugins 7.0.0, lib.lftest.test() treated the first or second element of a --test CSV argument as a filesystem path and returned the file contents as simulated standard output or standard error without path confinement. The hidden but production-accessible --test argument was accepted by sudo-authorized plugins, so an attacker controlling the nagios or icinga account could use check-plugins/deb-updates/deb-updates with its default QUERY=1 to disclose every line of a root-readable file. Approximately 22 other plugins exposed filtered content or a root file existence and readability oracle through the same helper, while check-plugins/network-bonding/network-bonding and check-plugins/openstack-swift-stat/openstack-swift-stat had direct read paths that bypassed the helper. The library fix confines fixture reads to the invoking plugin's unit-test directory and refuses unsafe anchors, and the plugin fix routes the two bypasses through that helper. These issues are fixed in linuxfabrik-lib 6.1.0 and Linuxfabrik Monitoring Plugins 7.0.0.
Attack profile
How easy it is to exploit
- Attack vector
- Local
- Complexity
- Low
- Privileges needed
- Low
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- None
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
5.5
linuxfabrik-lib: Arbitrary root file read via live --test argument (lib.lftest) across sudoers-whitelisted plugins (LPE)
linuxfabrik-lib provides Python modules for database access, caching, shell execution, and API integrations, and Linuxfabrik Monitoring Plugins uses its shared testing helper across check plugins. Prior to linuxfabrik-lib 6.1.0 and Linuxfabrik Monitoring Plugins 7.0.0, lib.lftest.test() treated the first or second element of a --test CSV argument as a filesystem path and returned the file contents as simulated standard output or standard error without path confinement. The hidden but production-accessible --test argument was accepted by sudo-authorized plugins, so an attacker controlling the nagios or icinga account could use check-plugins/deb-updates/deb-updates with its default QUERY=1 to disclose every line of a root-readable file. Approximately 22 other plugins exposed filtered content or a root file existence and readability oracle through the same helper, while check-plugins/network-bonding/network-bonding and check-plugins/openstack-swift-stat/openstack-swift-stat had direct read paths that bypassed the helper. The library fix confines fixture reads to the invoking plugin's unit-test directory and refuses unsafe anchors, and the plugin fix routes the two bypasses through that helper. These issues are fixed in linuxfabrik-lib 6.1.0 and Linuxfabrik Monitoring Plugins 7.0.0.
- Record
CVE-2026-73974- CVSS 3.1
- 5.5 Medium
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-22, CWE-269
- Updated
- 2026-11-02
EUVDEUVD-2026-62185
5.5
linuxfabrik-lib provides Python modules for database access, caching, shell execution, and API integrations, and Linuxfabrik Monitoring Plugins uses its shared testing helper across check plugins. Prior to linuxfabrik-lib 6.1.0 and Linuxfabrik Monitoring Plugins 7.0.0, lib.lftest.test() treated the first or second element of a --test CSV argument as a filesystem path and returned the file contents as simulated standard output or standard error without path confinement. The hidden but production-accessible --test argument was accepted by sudo-authorized plugins, so an attacker controlling the nagios or icinga account could use check-plugins/deb-updates/deb-updates with its default QUERY=1 to disclose every line of a root-readable file. Approximately 22 other plugins exposed filtered content or a root file existence and readability oracle through the same helper, while check-plugins/network-bonding/network-bonding and check-plugins/openstack-swift-stat/openstack-swift-stat had direct read paths that bypassed the helper. The library fix confines fixture reads to the invoking plugin's unit-test directory and refuses unsafe anchors, and the plugin fix routes the two bypasses through that helper. These issues are fixed in linuxfabrik-lib 6.1.0 and Linuxfabrik Monitoring Plugins 7.0.0.
- Record
EUVD-2026-62185- CVSS 3.1
- 5.5 Medium
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-rh9c-rqvg-f7pr
5.5
linuxfabrik-lib: Arbitrary root file read via live --test argument (lib.lftest) across sudoers-whitelisted plugins (LPE)
Summary
Every Linuxfabrik check plugin that supports the shared --test argument (routed through lib.lftest.test()) will, when --test is supplied, treat the first CSV element as a filesystem path and read its full contents as the plugin's simulated STDOUT — running as root when the plugin is invoked through the shipped nagios/icinga sudoers allowlist. --test is a live production argument (centrally mapped to argparse.SUPPRESS, so it is hidden from --help but still accepted on the command line), not a build-time-only gate. This yields an arbitrary root file-read primitive (full disclosure on deb-updates; filtered disclosure / existence-and-readability oracle on ~22 other whitelisted plugins), i.e. local privilege escalation from the nagios account to root.
Root Cause
lib.lftest.test(args)(lftest.pylines 659-664):stdout = args[0];if stdout and os.path.isfile(stdout): _, stdout = disk.read_file(stdout). Element[1] (stderr channel) is read the same way. There is no path confinement on the supplied path.check-plugins/deb-updates/deb-updates:--testis registered withtype=lib.args.csv(lines 78-82). When supplied, control flows tostdout, _, retc = lib.lftest.test(args.TEST)(line 143), bypassing the apt path (if args.TEST is None:at 121). Each returned line is stored as apackagerow and, under the default--query='1'(WHERE 1, matches all rows), every row is printed via'\n* '.join([row['package'] ...])→lib.base.oao(...).- The same
--test/lib.lftest.test()mechanism exists identically on ~22 whitelisted plugins (e.g.docker-info), each performing a rootopen()/read of the attacker-named path. Disclosure degree varies by each plugin's downstream parser: full (deb-updates), filtered (docker-infoechoes lines containingwarning:/error:;openvpn-client-listechoesCLIENT_LISTlines), or existence/readability oracle (JSON parsers).
Impact
An attacker controlling the low-privilege nagios/icinga account (the documented threat model for the shipped sudoers file — same precondition as CVE-2026-52817) obtains the full contents of any root-readable file via deb-updates (e.g. /etc/shadow, /root/.ssh/id_*, TLS keys, cloud credentials), plus a fleet-wide root file existence/readability oracle and filtered content leak via the other plugins → local privilege escalation to root.
Proof of Concept
Full disclosure (deb-updates):
sudo /usr/lib64/nagios/plugins/deb-updates --test=/etc/shadow,,0
Filtered disclosure / oracle (docker-info, target routed to the stderr channel that gets echoed):
sudo /usr/lib64/nagios/plugins/docker-info --test="dummy,/etc/shadow,0"
Attack Chain
- Entry:
sudo /usr/lib64/nagios/plugins/deb-updates --test=/etc/shadow,,0- Action: the nagios user invokes the whitelisted plugin as root with a
--testCSV whose element[0] is the target path and retc=0. - Guard: sudoers (Debian.sudoers:3) lists the binary only;
--testis not gated to test builds. - Bypass proof: CONTRIBUTING.md documents
--testas centrally mapped toargparse.SUPPRESS— hidden from--helpbut still accepted on the command line;lib.args.csvsplits/etc/shadow,,0into['/etc/shadow','','0'].
- Action: the nagios user invokes the whitelisted plugin as root with a
- Sink:
lib.lftest.test(args.TEST)(deb-updates:143) reads element[0] as a file, as root.- Guard: none — no path confinement on element[0].
- Bypass proof (from lib source):
lftest.py:661-664:stdout = args[0]; if stdout and os.path.isfile(stdout): _, stdout = disk.read_file(stdout)— element[0], if it exists on disk, is opened and its contents returned as stdout.retc=0(element[2]) so there is no earlycu()abort.
- Store + query: each line →
lib.db_sqlite.insert(conn, {'package': item}, ...); defaultQUERY='1'→SELECT * FROM deb_updates WHERE 1.- Guard:
--only-criticalor a restrictive--querywould filter, but both default to…
- Guard:
- Record
GHSA-rh9c-rqvg-f7pr- CVSS 3.1
- 5.5 Medium
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-22, CWE-269
- Updated
- 2026-11-02
NVD
5.5
linuxfabrik-lib provides Python modules for database access, caching, shell execution, and API integrations, and Linuxfabrik Monitoring Plugins uses its shared testing helper across check plugins. Prior to linuxfabrik-lib 6.1.0 and Linuxfabrik Monitoring Plugins 7.0.0, lib.lftest.test() treated the first or second element of a --test CSV argument as a filesystem path and returned the file contents as simulated standard output or standard error without path confinement. The hidden but production-accessible --test argument was accepted by sudo-authorized plugins, so an attacker controlling the nagios or icinga account could use check-plugins/deb-updates/deb-updates with its default QUERY=1 to disclose every line of a root-readable file. Approximately 22 other plugins exposed filtered content or a root file existence and readability oracle through the same helper, while check-plugins/network-bonding/network-bonding and check-plugins/openstack-swift-stat/openstack-swift-stat had direct read paths that bypassed the helper. The library fix confines fixture reads to the invoking plugin's unit-test directory and refuses unsafe anchors, and the plugin fix routes the two bypasses through that helper. These issues are fixed in linuxfabrik-lib 6.1.0 and Linuxfabrik Monitoring Plugins 7.0.0.
- Record
CVE-2026-73974- CVSS 3.1
- 5.5 Medium
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-22, CWE-269
- Updated
- 2026-11-02
OSV
5.5
linuxfabrik-lib: Arbitrary root file read via live --test argument (lib.lftest) across sudoers-whitelisted plugins (LPE)
linuxfabrik-lib provides Python modules for database access, caching, shell execution, and API integrations, and Linuxfabrik Monitoring Plugins uses its shared testing helper across check plugins. Prior to linuxfabrik-lib 6.1.0 and Linuxfabrik Monitoring Plugins 7.0.0, lib.lftest.test() treated the first or second element of a --test CSV argument as a filesystem path and returned the file contents as simulated standard output or standard error without path confinement. The hidden but production-accessible --test argument was accepted by sudo-authorized plugins, so an attacker controlling the nagios or icinga account could use check-plugins/deb-updates/deb-updates with its default QUERY=1 to disclose every line of a root-readable file. Approximately 22 other plugins exposed filtered content or a root file existence and readability oracle through the same helper, while check-plugins/network-bonding/network-bonding and check-plugins/openstack-swift-stat/openstack-swift-stat had direct read paths that bypassed the helper. The library fix confines fixture reads to the invoking plugin's unit-test directory and refuses unsafe anchors, and the plugin fix routes the two bypasses through that helper. These issues are fixed in linuxfabrik-lib 6.1.0 and Linuxfabrik Monitoring Plugins 7.0.0.
- Record
CVE-2026-73974- CVSS 3.1
- 5.5 Medium
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-22, CWE-269
- Updated
- 2026-11-02
OSVGHSA-rh9c-rqvg-f7pr
5.5
linuxfabrik-lib: Arbitrary root file read via live --test argument (lib.lftest) across sudoers-whitelisted plugins (LPE)
Summary
Every Linuxfabrik check plugin that supports the shared --test argument (routed through lib.lftest.test()) will, when --test is supplied, treat the first CSV element as a filesystem path and read its full contents as the plugin's simulated STDOUT — running as root when the plugin is invoked through the shipped nagios/icinga sudoers allowlist. --test is a live production argument (centrally mapped to argparse.SUPPRESS, so it is hidden from --help but still accepted on the command line), not a build-time-only gate. This yields an arbitrary root file-read primitive (full disclosure on deb-updates; filtered disclosure / existence-and-readability oracle on ~22 other whitelisted plugins), i.e. local privilege escalation from the nagios account to root.
Root Cause
lib.lftest.test(args)(lftest.pylines 659-664):stdout = args[0];if stdout and os.path.isfile(stdout): _, stdout = disk.read_file(stdout). Element[1] (stderr channel) is read the same way. There is no path confinement on the supplied path.check-plugins/deb-updates/deb-updates:--testis registered withtype=lib.args.csv(lines 78-82). When supplied, control flows tostdout, _, retc = lib.lftest.test(args.TEST)(line 143), bypassing the apt path (if args.TEST is None:at 121). Each returned line is stored as apackagerow and, under the default--query='1'(WHERE 1, matches all rows), every row is printed via'\n* '.join([row['package'] ...])→lib.base.oao(...).- The same
--test/lib.lftest.test()mechanism exists identically on ~22 whitelisted plugins (e.g.docker-info), each performing a rootopen()/read of the attacker-named path. Disclosure degree varies by each plugin's downstream parser: full (deb-updates), filtered (docker-infoechoes lines containingwarning:/error:;openvpn-client-listechoesCLIENT_LISTlines), or existence/readability oracle (JSON parsers).
Impact
An attacker controlling the low-privilege nagios/icinga account (the documented threat model for the shipped sudoers file — same precondition as CVE-2026-52817) obtains the full contents of any root-readable file via deb-updates (e.g. /etc/shadow, /root/.ssh/id_*, TLS keys, cloud credentials), plus a fleet-wide root file existence/readability oracle and filtered content leak via the other plugins → local privilege escalation to root.
Proof of Concept
Full disclosure (deb-updates):
sudo /usr/lib64/nagios/plugins/deb-updates --test=/etc/shadow,,0
Filtered disclosure / oracle (docker-info, target routed to the stderr channel that gets echoed):
sudo /usr/lib64/nagios/plugins/docker-info --test="dummy,/etc/shadow,0"
Attack Chain
- Entry:
sudo /usr/lib64/nagios/plugins/deb-updates --test=/etc/shadow,,0- Action: the nagios user invokes the whitelisted plugin as root with a
--testCSV whose element[0] is the target path and retc=0. - Guard: sudoers (Debian.sudoers:3) lists the binary only;
--testis not gated to test builds. - Bypass proof: CONTRIBUTING.md documents
--testas centrally mapped toargparse.SUPPRESS— hidden from--helpbut still accepted on the command line;lib.args.csvsplits/etc/shadow,,0into['/etc/shadow','','0'].
- Action: the nagios user invokes the whitelisted plugin as root with a
- Sink:
lib.lftest.test(args.TEST)(deb-updates:143) reads element[0] as a file, as root.- Guard: none — no path confinement on element[0].
- Bypass proof (from lib source):
lftest.py:661-664:stdout = args[0]; if stdout and os.path.isfile(stdout): _, stdout = disk.read_file(stdout)— element[0], if it exists on disk, is opened and its contents returned as stdout.retc=0(element[2]) so there is no earlycu()abort.
- Store + query: each line →
lib.db_sqlite.insert(conn, {'package': item}, ...); defaultQUERY='1'→SELECT * FROM deb_updates WHERE 1.- Guard:
--only-criticalor a restrictive--querywould filter, but both default to…
- Guard:
- Record
GHSA-rh9c-rqvg-f7pr- CVSS 3.1
- 5.5 Medium
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-22, CWE-269
- Updated
- 2026-11-02
OSVPYSEC-2026-3682
5.5
linuxfabrik-lib: Arbitrary root file read via live --test argument (lib.lftest) across sudoers-whitelisted plugins (LPE)
Summary
Every Linuxfabrik check plugin that supports the shared --test argument (routed through lib.lftest.test()) will, when --test is supplied, treat the first CSV element as a filesystem path and read its full contents as the plugin's simulated STDOUT — running as root when the plugin is invoked through the shipped nagios/icinga sudoers allowlist. --test is a live production argument (centrally mapped to argparse.SUPPRESS, so it is hidden from --help but still accepted on the command line), not a build-time-only gate. This yields an arbitrary root file-read primitive (full disclosure on deb-updates; filtered disclosure / existence-and-readability oracle on ~22 other whitelisted plugins), i.e. local privilege escalation from the nagios account to root.
Root Cause
lib.lftest.test(args)(lftest.pylines 659-664):stdout = args[0];if stdout and os.path.isfile(stdout): _, stdout = disk.read_file(stdout). Element[1] (stderr channel) is read the same way. There is no path confinement on the supplied path.check-plugins/deb-updates/deb-updates:--testis registered withtype=lib.args.csv(lines 78-82). When supplied, control flows tostdout, _, retc = lib.lftest.test(args.TEST)(line 143), bypassing the apt path (if args.TEST is None:at 121). Each returned line is stored as apackagerow and, under the default--query='1'(WHERE 1, matches all rows), every row is printed via'\n* '.join([row['package'] ...])→lib.base.oao(...).- The same
--test/lib.lftest.test()mechanism exists identically on ~22 whitelisted plugins (e.g.docker-info), each performing a rootopen()/read of the attacker-named path. Disclosure degree varies by each plugin's downstream parser: full (deb-updates), filtered (docker-infoechoes lines containingwarning:/error:;openvpn-client-listechoesCLIENT_LISTlines), or existence/readability oracle (JSON parsers).
Impact
An attacker controlling the low-privilege nagios/icinga account (the documented threat model for the shipped sudoers file — same precondition as CVE-2026-52817) obtains the full contents of any root-readable file via deb-updates (e.g. /etc/shadow, /root/.ssh/id_*, TLS keys, cloud credentials), plus a fleet-wide root file existence/readability oracle and filtered content leak via the other plugins → local privilege escalation to root.
Proof of Concept
Full disclosure (deb-updates):
sudo /usr/lib64/nagios/plugins/deb-updates --test=/etc/shadow,,0
Filtered disclosure / oracle (docker-info, target routed to the stderr channel that gets echoed):
sudo /usr/lib64/nagios/plugins/docker-info --test="dummy,/etc/shadow,0"
Attack Chain
- Entry:
sudo /usr/lib64/nagios/plugins/deb-updates --test=/etc/shadow,,0- Action: the nagios user invokes the whitelisted plugin as root with a
--testCSV whose element[0] is the target path and retc=0. - Guard: sudoers (Debian.sudoers:3) lists the binary only;
--testis not gated to test builds. - Bypass proof: CONTRIBUTING.md documents
--testas centrally mapped toargparse.SUPPRESS— hidden from--helpbut still accepted on the command line;lib.args.csvsplits/etc/shadow,,0into['/etc/shadow','','0'].
- Action: the nagios user invokes the whitelisted plugin as root with a
- Sink:
lib.lftest.test(args.TEST)(deb-updates:143) reads element[0] as a file, as root.- Guard: none — no path confinement on element[0].
- Bypass proof (from lib source):
lftest.py:661-664:stdout = args[0]; if stdout and os.path.isfile(stdout): _, stdout = disk.read_file(stdout)— element[0], if it exists on disk, is opened and its contents returned as stdout.retc=0(element[2]) so there is no earlycu()abort.
- Store + query: each line →
lib.db_sqlite.insert(conn, {'package': item}, ...); defaultQUERY='1'→SELECT * FROM deb_updates WHERE 1.- Guard:
--only-criticalor a restrictive--querywould filter, but both default to…
- Guard:
- Record
PYSEC-2026-3682- CVSS 3.1
- 5.5 Medium
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N - Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
linuxfabrik-libPyPI |
before 6.1.0 | 6.1.0 |
linuxfabrik-libPyPI |
before 6.1.0, plus listed versions 2.0.0.02.0.0.72.1.0.02.1.0.42.1.1.15 Show 23 moreShow less2.1.1.52.1.1.72.2.02.2.12.3.02.4.03.0.03.1.03.1.13.2.03.3.03.4.03.4.14.0.04.0.14.0.24.1.04.2.04.3.04.4.05.0.05.1.06.0.0 |
6.1.0 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-73974 is a medium vulnerability (CVSS 5.5) in Linuxfabrik Lib, published August 18, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.17%, the 6th percentile. Fixed in linuxfabrik-lib 6.1.0.
References
github.com/Linuxfabrik/monitoring-plugins/security/advisories/GHSA-rh9c-rqvg-f7pr
github.com/Linuxfabrik/lib/commit/d665042c55fae83a295ebc0023e8b77f6c473a28
github.com/Linuxfabrik/monitoring-plugins/commit/f6680a9e4b39569f318feefdb2f51e5d18c7dad5
github.com/Linuxfabrik/lib/releases/tag/v6.1.0
github.com/Linuxfabrik/monitoring-plugins/releases/tag/v7.0.0
github.com/advisories/GHSA-rh9c-rqvg-f7pr
Left out here: the rest of 3 source descriptions. The JSON record has them.