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

Sicherheits-Audit — Juli 2026 — Runde 9

Code-Security-Review
NetMon Roots v1.1.19 — Release-Stand

Neuntes automatisiertes Security-Review auf Basis von Claude Fable 5 — erstmals auf dem finalen Release-Stand v1.1.19 statt auf einem Zwischenstand. Schwerpunkte dieser Runde: der VPN/UFW-Killswitch-Reconcile, die DNS-Startup-Recovery, der In-App-Update-Check, die Debian-Maintainer-Skripte (Install/Deinstall als root) sowie der komplette Release-Verifikationspfad (SHA256SUMS + minisign). Anders als in den Vorrunden wurden diesmal zwei belastbare Schwachstellen mittleren Schweregrads bestätigt — eine fehlende Schema-Allowlist beim automatischen Öffnen der Update-URL und ein Fail-Open des Killswitch in frühen Fehlerpfaden des VPN-Slot-Wechsels. Beide wurden umgesetzt, mit Regressionstests abgesichert und verifiziert. Die Release-Signaturkette (minisign) wurde empirisch geprüft und ist gültig.

← Runde 8 (0 Findings — Kindersicherung dokumentiert)
PDF herunterladen Findings Release-Verifikation Kategorien

0 kritische — 0 hohe — 2 mittlere Findings (beide umgesetzt & verifiziert)

Das Review des finalen 1.1.19-Release-Stands identifizierte zwei belastbare Schwachstellen mittleren Schweregrads, die von dedizierten Validierungs-Sub-Agenten je mit Konfidenz 8/10 bestätigt wurden. F1: Der In-App-Update-Check übergab eine aus einer Remote-Versionsdatei stammende download_url ungeprüft an xdg-open — ohne die http/https-Allowlist, die an vergleichbaren Stellen (Secure-Browser-Favicon, Radio-Logo) bereits existiert. F2: Schlug ein VPN-Slot-Wechsel in einem frühen Fehlerpfad fehl, setzte NetMon die Firewall bedingungslos auf default allow outgoing zurück — auch wenn der Nutzer den Killswitch bewusst aktiv hatte, wodurch Klartext-Traffic entweichen konnte. Beide Findings wurden direkt behoben (Schema-Allowlist + Host-Pin für die Update-URL; Killswitch-erhaltender Recover-Pfad), mit neuen Regressionstests abgesichert und verifiziert. Zusätzlich wurde die Release-Verifikationskette (SHA256SUMS + minisign) empirisch bestätigt und eine UX-Empfehlung zur Sichtbarkeit der Signaturprüfung festgehalten. Alle Runde-7/8-Härtungen sind intakt; die Kindersicherung bleibt als bewusste Design-Entscheidung dokumentiert.

Datum
18. Juli 2026
Analysierte Version
v1.1.19 — finaler Release-Stand
Kritische Findings
0
Hohe Findings
0
Mittlere Findings
2 (beide behoben)
Härtungen umgesetzt
2 + Regressionstests
Release-Signatur (minisign)
gültig verifiziert
Analysewerkzeug
Claude Fable 5

Umfang & Methodik

Geprüft wurde der finale Release-Stand v1.1.19 (constants.py = 1.1.19, deb-control, latest-version.json und die Download-Seiten stimmen überein). Schwerpunkt auf den seit den Vorrunden nicht im Fokus gewesenen, sicherheitskritischen Pfaden: dem VPN/UFW-Killswitch- Reconcile (vpn_controller.py, firewall_controller.py), der DNS-Startup-Recovery (app.py, dns_control_service.py), dem In-App-Update-Check (_fetch_latest_release_info(), _open_url_with_xdg_open()), den Debian-Maintainer-Skripten (postinst/prerm aus der gebauten .deb) und dem Release-Verifikationspfad (verify_netmon_download.sh, verify_netmon_signature.sh, SHA256SUMS.minisig). Die in Runde 7/8 gehärteten Bereiche wurden auf Regressionen gegengeprüft.

Phase 1 — Release-Recon

Verifikation der Artefakte: sha256sum -c SHA256SUMS (alle drei OK), minisign -V gegen den gepinnten Public Key (Signatur gültig). Extraktion und Review der .deb-Maintainer-Skripte. Versionskonsistenz-Abgleich.

Phase 2 — Kandidaten-Analyse

Ein Analyse-Sub-Agent verfolgte Datenflüsse von Fremdeingaben (Update-/API-Antworten, VPN-Profil-/Slot-Daten, Install-Zeit-Zustand) bis zu privilegierten Senken (ufw/nmcli/ wg-quick, xdg-open, root-cp/ chown). 5 Kandidaten identifiziert.

Phase 3 — False-Positive-Validierung

Die zwei belastbaren Kandidaten wurden von je einem eigenen Validierungs-Sub-Agenten gegengeprüft (beide Konfidenz 8/10, MEDIUM). Drei weitere Kandidaten (postinst-DNS-Policy, State-Datei-Parsing, root-Symlink-chown) lagen als Policy-/Grenzfall unter der Schwelle.

Phase 4 — Härtung & Regressionscheck

Beide MEDIUM-Findings wurden umgesetzt, mit neuen Regressionstests abgesichert und verifiziert. Suiten erneut ausgeführt: Killswitch/VPN/DNS/Firewall (253) und Diagnostik/Update-Check (80) — alle sicherheitsrelevanten Tests grün.

Bestätigte Findings (Runde 9)

Zwei Findings mittleren Schweregrads wurden bestätigt (Konfidenz je 8/10) und direkt behoben. Keine kritischen oder hohen, keine klar remote-ausnutzbaren RCE-Befunde.

F1 — Update-Check öffnet server-gelieferte URL ohne Schema-Allowlist

Mittel · 8/10 Behoben

Datei: netmon/app.py_fetch_latest_release_info(), check_about_latest_version(), _open_url_with_xdg_open().

Der In-App-Update-Check lädt latest-version.json per HTTPS und übernimmt das Feld download_url daraus ungeprüft. Wird beim Öffnen des „Über“-Dialogs eine neuere Version erkannt, wird diese URL ohne weiteren Klick an xdg-open übergeben — ganz ohne Schema-/Host-Prüfung. Genau diese http/https-Allowlist existiert an vergleichbaren Stellen bereits (Secure-Browser-fetch_url(), Radio- _station_logo_url()); der Update-Pfad war die einzige übersehene Fremd-URL-Senke.

Bedrohung: Ein kompromittierter Server/CDN (im Bedrohungsmodell ausdrücklich enthalten) kann eine download_url mit beliebigem Schema liefern (file://, Custom-Handler wie vnc://) oder auf eine Phishing-Seite verweisen, die xdg-open an den zuständigen Desktop-Handler weiterreicht. Kein direktes RCE (Listenform-Popen, keine Shell-Injection), aber zuverlässig für Phishing und — situativ — zum Ansteuern eines registrierten Scheme-Handlers.

Härtung umgesetzt & verifiziert: _open_url_with_xdg_open() begrenzt Ziel-URLs jetzt auf http/https (deckt alle Aufrufer ab); zusätzlich lässt der Update-Pfad über _is_trusted_update_url() nur eine netmonroots.com-URL automatisch öffnen und fällt sonst auf die fest konfigurierte Download-Seite zurück. Mit Regressionstests abgesichert (test_is_trusted_update_url_accepts_only_netmonroots_https, test_open_url_with_xdg_open_rejects_non_web_scheme).

F2 — Killswitch-Fail-Open in frühen VPN-Slot-Wechsel-Fehlerpfaden

Mittel · 8/10 Behoben

Dateien: netmon/features/vpn_controller.py (vpn_switch()), netmon/features/firewall_controller.py (recover_firewall_after_killswitch_failure()).

recover_firewall_after_killswitch_failure() setzt die Firewall bedingungslos auf ufw default allow outgoing. Sie wurde in drei frühen Fehlerpfaden von vpn_switch() aufgerufen (leeres Ziel, nicht auflösbares Runtime-Profil, WG-Cleanup-Fehler) — ohne zu prüfen, ob der Killswitch zu diesem Zeitpunkt bewusst aktiv war.

Bedrohung: Nutzer hat Killswitch AN + VPN aktiv, wählt einen VPN-Slot, dessen Profil gelöscht/umbenannt wurde oder dessen IPv4-Runtime-Kopie fehlt → vpn_switch() bricht früh ab → die deny-outgoing-Garantie wird still auf allow zurückgesetzt, und Klartext-Traffic kann das System verlassen, obwohl der Nutzer Killswitch-Schutz erwartet. Das ist genau der Leak, den das Feature verhindern soll — ein Fail-Open in einer Kontrolle, deren einziger Zweck Fail-Closed ist. (Kein Remote-Trigger; die UI-Statusanzeige wechselt zwar auf Rot, es gab aber keinen Warnhinweis.)

Härtung umgesetzt & verifiziert: Die drei Aufrufstellen nutzen jetzt _recover_firewall_preserving_killswitch(): War der Killswitch aktiv (killswitch_is_on(), ausgewertet vor jeder Zustandsänderung), wird die deny-outgoing-Policy per idempotentem _killswitch_on_sync() erhalten statt geöffnet; nur ohne aktiven Killswitch wird wie bisher auf allow-outgoing zurückgesetzt, damit sich der Nutzer nicht aussperrt. Mit Regressionstests abgesichert (test_recover_preserving_killswitch_*, test_vpn_switch_empty_target_preserves_active_killswitch).

Release-Verifikation & weitere Beobachtungen

🔑

Signaturkette technisch dicht — Empfehlung zur Sichtbarkeit

SHA256SUMS deckt alle drei Artefakte korrekt ab (sha256sum -c OK) und ist per minisign signiert; die Signatur wurde gegen den gepinnten Public Key gültig verifiziert. Das Verifier-Skript prüft jedoch nur die Hashes, und die prominente „Schnellprüfung“ auf der Downloadseite empfiehlt ebenfalls nur sha256sum -c — ein MitM, der .deb und SHA256SUMS gemeinsam ersetzt, bestünde diesen Schnellcheck. Empfehlung (Doku/UX, keine Code-Lücke): die minisign-Vollprüfung als empfohlenen Standardweg hervorheben statt als optionalen „falls signiert“-Zusatz.

🔐

Kindersicherung — weiterhin bewusste Design-Entscheidung

Die PBKDF2-gestützte Kindersicherung im Secure-Browser bleibt wie in Runde 8 dokumentiert: Alltagshürde gegen Gelegenheitszugriff im selben Konto, keine harte Grenze gegen technisch versierte Nutzer mit Kontozugriff. Keine Codeänderung, unverändert gültig.

📋

postinst setzt aktive NM-DNS auf 8.8.8.8 — Policy-Hinweis

Das root-postinst biegt aktive NetworkManager-Verbindungen bei der Installation auf ipv4.dns 8.8.8.8 um (Vorzustand wird gesichert und in prerm restauriert). Funktional sauber, aber für ein Privacy-Tool eine überraschende Richtung. Empfehlung: Opt-in statt hart verdrahtetem Public-Resolver. Kein ausnutzbarer Befund (State-Datei 0600 root, Argumentlisten-Aufrufe, keine Injection). Keine Codeänderung in dieser Runde — als Design-Entscheidung des Projektverantwortlichen offen.

Umgesetzte Härtungsmaßnahmen (Runde 9)

🔒

Schema-Allowlist + Host-Pin für die Update-URL — app.py

_open_url_with_xdg_open() lässt nur noch http/https zu; _is_trusted_update_url() beschränkt die automatisch geöffnete Update-URL zusätzlich auf die netmonroots.com-Domain.

🛡

Killswitch-erhaltender Recover-Pfad — vpn_controller.py

_recover_firewall_preserving_killswitch() hält die deny-outgoing-Policy bei aktivem Killswitch aufrecht, statt sie bei einem fehlgeschlagenen Slot-Wechsel still zu öffnen.

🧪

Neue Regressionstests

Fünf neue Tests in test_netmon_diagnostics.py und test_netmon_killswitch.py sichern die Update-URL- Allowlist und das Killswitch-erhaltende Recover-Verhalten ab. Sicherheitsrelevante Suiten (253 + 80 Tests) sind grün.

Geprüfte Sicherheitskategorien

Kategorie Geprüft Ergebnis
Sicherheitskontroll-Umgehung (Killswitch Fail-Open) Ja F2 → behoben (fail-closed)
Unvalidierte Fremd-URL an Desktop-Handler (xdg-open) Ja F1 → behoben (Allowlist+Host-Pin)
Command-/Argument-Injection (ufw/nmcli/wg-quick, subprocess) Ja Kein Finding (durchgängig list-form)
DNS-Startup-Recovery (privilegierte nmcli/resolvectl-Aufrufe) Ja Kein Finding (validiert, fail-safe)
Debian-Maintainer-Skripte (root: cp/chown, State-Parsing) Ja Kein ausnutzbarer Befund (Policy-Hinweis)
Release-Integrität (SHA256SUMS + minisign) Ja Signatur gültig (UX-Empfehlung)
Pfad-Traversal / TOCTOU / Symlink (privilegierte Dateiops) Ja Kein Finding im Threat-Model
Autorisierung / Kindersicherung Ja Bewusste Design-Entscheidung
Unsichere Deserialisierung (pickle, yaml.load, eval, shell=True) Ja Kein Finding
Regression der Runde-7/8-Härtungen Ja Alle intakt
Versionskonsistenz (App / deb / Site / latest-version.json) Ja Durchgängig 1.1.19

Auditor: Claude Fable 5 (Anthropic) — Analyse-Sub-Agent + zwei dedizierte False-Positive-Validierungs-Sub-Agenten
Projektverantwortlicher: Sven Fröhlich
Datum: 18. Juli 2026
Analysierter Codestand: finaler Release-Stand v1.1.19 (Arbeitsstand auf c2087b63), einschließlich der gebauten netmon_1.1.19_all.deb und der signierten Release-Artefakte — Runde 9
Methode: Statische Code-Analyse + manuelle Datenfluss-Verifikation + empirische Verifikation der Release-Signatur (sha256sum -c + minisign -V) + Konfidenz-gescorte FP-Validierung pro Kandidat + Umsetzung von zwei Defense-in-Depth-Härtungen mit Regressionstests + Regressions-Gegenprüfung der Runde-7/8-Härtungen (Suiten: 253 + 80 Tests, alle sicherheitsrelevanten bestanden) — kein Laufzeit-Penetrationstest
Haftungsausschluss: Dieses Audit ersetzt keinen professionellen Penetrationstest durch eine zertifizierte Sicherheitsfirma. Die Analyse beschränkt sich auf den angegebenen Codestand. Nicht erfasst werden: Laufzeitverhalten, abhängige Systembibliotheken, Netzwerkkonfiguration und soziale Angriffsvektoren.

Zur Downloadseite   •   Aktuelles   •   Dokumentation   •   Runde 8