NETMON ROOTS MONITOR. CONTROL. UNDERSTAND. BACK TO THE ROOTS.
DE EN

Security Audit — September 2026 — Round 12

Code and Release Security Review
NetMon Roots v1.1.21

Round 12 reviewed 96 commits since round 11, the large tab UI extraction, privileged system paths, and the release supply chain. The refactoring adds no new shell, network, or privilege sink. The medium DNS finding, TAR link handling, version drift, and stale support matrix have been remediated. The real Minisign public key is pinned in the security policy and canonical repository file under key ID 54BF5F1867BDD004.

Download round 12 PDF

✓

All round 12 findings remediated

The Debian installer no longer changes DNS profiles, Firefox imports accept only bounded regular files and directories, and release builds now have hard version and signature gates. The real public key is pinned in the repository outside the download origin, and builds reject mismatched keys.

Date
September 19, 2026
Reviewed version
v1.1.21
Critical / High
0 / 0
Open Medium / Low
0 / 0
Test suite
2595 passed, 2 skipped
Dependencies
No known advisories

Round 12 findings

NM-R12-01 — Remediated: the Debian postinst no longer changes active DNS profiles. Upgrades restore state left by older packages and remove that legacy state.

NM-R12-02 — Remediated: Firefox TAR extraction accepts only regular files and directories, rejects links and special files, validates every target path, and enforces download and extraction limits.

NM-R12-03 — Remediated: release builds now require Minisign keys and verify the generated signature. The verifier supports an independently obtained key pin. Key ID 54BF5F1867BDD004 is pinned in SECURITY.md and the canonical repository key file; builds reject mismatched keys.

NM-R12-04 — Remediated: package, site, and docs builds derive version 1.1.21 from the canonical app constant. A consistency gate checks the public release metadata before builds.

NM-R12-05 — Remediated: SECURITY.md now identifies 1.1.21 as the supported release line.

Verification

Ruff and formatting checks passed. The initial repository-wide high heuristics were manually validated and technically clarified; the final Bandit scan at the high-severity threshold reports no findings. pip-audit found no known vulnerability in the currently resolved requirements. Shellcheck and the GUI smoke test passed. The focused R12 remediation set completed with 33 passed tests; the full suite completed with 2595 passed and 2 skipped tests.

This static review does not replace an independent penetration test. The detailed technical report is stored as docs/SECURITY_AUDIT_2026_R12.md in the repository.

Previous round 11 — full report

Security Audit — July 2026 — Round 11

Code Security Review
NetMon Roots v1.1.20

Eleventh automated security review based on Claude Fable 5, covering the full diff since the round 10 state — 215 commits, the vast majority of them mechanical refactoring. The security-relevant new work was the still-unreleased UFW sysctl override feature, which rewrites /etc/ufw/sysctl.conf as root, plus a new runtime measurement module. The scope was deliberately widened by a first as-is review of the radio sinks, which had never fallen inside a diff-based scope. This round produced no finding above the reporting threshold — of three candidates, one was refuted and one downgraded. Eight defense-in-depth hardening measures were implemented anyway, backed by 26 regression tests.

Download PDF Summary Candidates Hardening
✓

0 critical — 0 high — 0 medium findings (8 hardening measures)

The review found no vulnerability above the 8/10 reporting threshold. Three candidates in the new UFW sysctl feature were re-examined by independent validation sub-agents tasked with refuting them: one was refuted (2/10 — its central premise did not survive empirical checking), one was downgraded to LOW (6/10 — the mechanism is real, the claimed loss of hardening is not), and the third is a pure defense-in-depth inconsistency. All three were fixed regardless. A first as-is review of the radio sinks — code unchanged for several rounds and therefore never inside a diff scope — produced four further hardening measures. All hardening from rounds 7 through 10 is intact; the child-lock remains documented as a deliberate design decision.

Date
July 29, 2026
Reviewed version
v1.1.20
Critical findings
0
High findings
0
Medium findings
0
Test suite
2562 passed, 2 skipped

Scope and method

The reviewed scope was the full diff since the round 10 state (445279ac, July 20, 2026) up to the current working state, including uncommitted changes: 215 commits and 468 files, but only about 3,750 lines of production code across 22 modules — the remainder is tests and refactoring documentation.

  • New UFW sysctl override feature writing to /etc/ufw/sysctl.conf as root
  • New runtime measurement module and its hook into the central command path
  • Large radio refactoring, proven behaviour-preserving via a normalised content diff
  • As-is review of the radio sinks (mpv/ffmpeg invocation, ICY metadata, recording filenames, playlist parsing)
  • Regression re-check of the round 9 and 10 hardening — all intact

Candidates and validation

K1 — stderr contamination in the read-modify-write of /etc/ufw/sysctl.conf [LOW, 6/10, hardened]: the file is read via sudo -n cat through a helper that merges stderr into stdout, so a sudo warning ("unable to resolve host …") arrives with exit code 0 inside the supposed file content and would be written back into a root config file. The reporter's claim that this could disable hardening at boot was refuted empirically: sysctl warns about a malformed line but continues processing the remaining lines and returns 0, and ufw-init ignores errors anyway. The reporter also missed that a write-back only happens on an actual change, and that the same pattern already existed in committed code. The warning text is not attacker-controlled, so there is no injection vector. Hardened regardless with a plausibility gate that aborts the run — at both read sites — as soon as the content contains a line that cannot be a sysctl config line.

K2 — new write sink missing its sister sink's allowlist [LOW, 3/10, hardened]: the key allowlist introduced in round 10 sits deliberately at the write sink as a second line of defense, but the new sink writing to /etc/ufw/sysctl.conf — a file that per its own header overrides /etc/sysctl.conf and /etc/sysctl.d — carried none of those checks. Not exploitable today (the only caller passes a module constant, and no data flow from transfer packages or remote JSON reaches this sink), but a regression against a documented protection decision. The sink now applies the same allowlist and value validation as its sister.

K3 — "sysctl re-apply silently reverts kernel hardening" [REFUTED, 2/10]: the validator extracted the original ufw_0.36.2-6_all.deb and showed that /etc/ufw/sysctl.conf contains no rp_filter at all, so the central premise was wrong. The only real overlap with the NetMon baseline is log_martians — and the code under complaint is precisely the countermeasure for it, since the package ships log_martians=0 against NetMon's target of 1. A downstream value verification also exists: a baseline re-check reads the live kernel values after every step. Finally, the direction of the deviation was misjudged — rp_filter=1 is stricter than NetMon's deliberate 2, so security would rise, not fall. No code change needed.

Implemented hardening

  • Key allowlist and value validation at the UFW sysctl write sink
  • Plausibility gate aborting any read-modify-write whose content contains a non-config line (both read sites)
  • -- option terminator before the mpv media argument, so a playlist entry named --script=payload.lua cannot become an option
  • Handover payload now passes through the stream URL scheme allowlist — the only path that bypassed it
  • mpv IPC socket moved into XDG_RUNTIME_DIR or a private 0700 directory (socket access means mpv's run command)
  • Explicit ffmpeg protocol allowlist without file, so a crafted HLS/concat playlist cannot pull local files into a recording
  • Value-side redaction in the measurement log — previously only metadata keys were checked, not values
  • Measurement log opened with O_NOFOLLOW and mode 0600; rotation skips symlinked paths
  • 26 new regression tests; full suite 2562 passed, 2 skipped

Auditor: Claude Fable 5 (Anthropic) — four analysis sub-agents plus two independent false-positive validation sub-agents
Project owner: Sven Froehlich
Date: July 29, 2026
Reviewed state: NetMon 1.1.20 working state (diff since the round 10 state 445279ac, including uncommitted changes), extended by an as-is review of the radio sinks
Method: static code analysis with manual data-flow verification, a normalised content diff for the refactoring bulk, confidence-scored false-positive validation with empirical counter-checks (package extraction, sysctl behaviour tests), eight hardening measures with 26 regression tests, and a regression re-check of the previous rounds' hardening — no runtime penetration testing

Download page   •   Updates   •   Documentation   •   Legal