Sicherheits-Audit — Juli 2026 — Runde 7
Code-Security-Review
NetMon Roots v1.1.18
Siebtes automatisiertes Security-Review auf Basis von
Claude Fable 5. Schwerpunkt dieser Runde: die seit Runde 6
neu hinzugekommene RKHunter-Referenzuebernahme
(rkhunter --propupd über
run_rkhunter_propupd() /
restore_property_database() in
rkhunter_manager.py), der neue
deterministische Analysedienst
(rkhunter_analysis_service.py) samt seinem
propupd-Sicherheits-Gate, die zusätzlichen
privilegierten Hilfskommandos im Scan-Worker
(dpkg -V, dpkg -S,
file -b, cat /var/log/rkhunter.log)
sowie die neue ClamAV-Signaturdatenbank-Auswahl
(clamav_database_args()) und die konfigurierbaren
Schnellscan-Pfade. Wie in Runde 6 wurden
keine ausnutzbaren Schwachstellen bestätigt:
vier Kandidaten wurden von dedizierten Validierungs-Sub-Agenten
geprüft — zwei als „kein Finding“ verworfen, zwei
als sinnvolle Defense-in-Depth-Härtungen unterhalb
der Konfidenzschwelle. Beide Härtungen wurden anschließend
umgesetzt und empirisch verifiziert
(verschärfter propupd-Klassifizierer, Eigentümer-/
Rechte-Prüfung der ClamAV-Signaturdatenbank) und mit neuen
Regressionstests abgesichert.
Umfang & Methodik
Schwerpunkt dieser Runde war die seit dem Runde-6-Snapshot neu
hinzugekommene bzw. veränderte Angriffsfläche im
Arbeitsstand: die RKHunter-Referenzuebernahme
(run_rkhunter_propupd(),
backup_property_database(),
restore_property_database()), der neue deterministische
Analysedienst mit seinem propupd-Sicherheits-Gate
(analyze_rkhunter_output(),
_rkhunter_propupd_gate_valid()), die im Scan-Worker
neu ausgeführten privilegierten Hilfskommandos
(dpkg -V/-S, file -b,
cat /var/log/rkhunter.log) sowie die neue
ClamAV-Signaturdatenbank-Auswahl
(clamav_database_args(),
clamav_user_database_dir()) und die konfigurierbaren
Schnellscan-Pfade. Die in Runde 6 gehärteten Bereiche des
Secure Browser Managers und des Agent-Pfad-Confinements
waren in diesem Arbeitsstand unverändert und daher nicht im
Fokus.
Phase 1 — Diff- & Reconnaissance
Vollständiger git diff gegen den letzten Commit
(c2087b63) plus Sichtung der neuen unversionierten Dateien
(rkhunter_analysis_service.py und die zugehörigen
Testdateien). Gezieltes Lesen der neuen RKHunter-Pfade und der
ClamAV-Datenbankwahl.
Phase 2 — Kandidaten-Analyse
Ein dedizierter Analyse-Sub-Agent verfolgte Datenflussketten von
rkhunter-/dpkg-Ausgaben und lokalen Eingaben bis zu sensiblen
Operationen (sudo cp -a, subprocess.run,
--propupd, clamscan --database).
4 Kandidaten identifiziert.
Phase 3 — False-Positive-Validierung
Für jeden Kandidaten lief eine eigene Validierung mit striktem FP-Filter und Konfidenz-Scoring — ergänzt um eine empirische Reproduktion des Klassifizierer-Verhaltens am realen Modul. Ergebnis: 2 kein Finding, 2 unter der Schwelle (2–3 / 10).
Phase 4 — Härtung & Regressionscheck
Die beiden Kandidaten unter der Schwelle wurden als
Defense-in-Depth umgesetzt, empirisch am realen Modul gegengeprüft
und mit neuen Regressionstests abgesichert. Suiten erneut ausgeführt:
test_rkhunter_analysis_service.py,
test_rkhunter_security_flow.py,
test_rkhunter_manager.py,
test_clamav_controller.py —
59 Tests, alle grün.
Sicherheitsfokus (Runde 7)
| Datei / Modul | Fokus | Ergebnis |
|---|---|---|
rkhunter_analysis_service.py — analyze_rkhunter_output() |
Zu permissive FP-Klassifizierung: jede /etc/*.conf-
Änderung und jeder docker/vscode-
Substring gilt als „expected“ und kann das
propupd-Gate passieren |
K1 → gehärtet |
clamav_controller.py — clamav_user_database_dir() |
ClamAV-Signaturdatenbank in einem vorhersagbaren
/tmp-Pfad (--database) |
K2 → gehärtet |
security_audit_controller.py — rkhunter_scan_worker() |
Neue privilegierte Hilfskommandos mit Pfaden aus der
rkhunter-Ausgabe (dpkg -S, file -b)
— Command-/Argument-Injection? |
Kein Finding (list-form) |
rkhunter_manager.py — backup/restore_property_database() |
sudo cp -a auf die rkhunter-Referenz-DB —
Pfad-Kontrolle? |
Kein Finding (fail-closed) |
| Runde-6-Bereiche (Browser-Manager, Agent-Confinement) | In diesem Arbeitsstand unverändert — Gegenprüfung | Weiterhin wirksam |
Außerhalb des Scopes: die reine Kosmetik-/UI-Diffs
(security_tabs.py, Sprachdateien) und das
Verpackungs-Cleanup (rm -f Code-the-Classics.zip im
Deb-Build) enthalten keine sicherheitsrelevante Logik. Das Audit ersetzt
keinen Laufzeit-Penetrationstest.
Bewertete Kandidaten
Vier Kandidaten wurden identifiziert und jeweils gegengeprüft. Keiner erreichte die Konfidenzschwelle von 8/10 für ein bestätigtes, ausnutzbares Finding — im Wesentlichen, weil es sich um ein Einzelnutzer-Desktop-Werkzeug handelt, bei dem die vermeintliche „Angreifer“-Eingabe entweder vom selben lokalen Nutzer stammt oder bereits lokale Root-Rechte voraussetzt. Zwei Kandidaten wurden als „kein Finding“ verworfen, zwei als Defense-in-Depth direkt umgesetzt und verifiziert.
K1 — Zu permissive FP-Klassifizierung im propupd-Sicherheits-Gate
Konfidenz 3/10
Gehärtet
Datei: netmon/services/rkhunter_analysis_service.py
— _classify_rkhunter_line() /
analyze_rkhunter_output(), ausgewertet in
_rkhunter_propupd_gate_valid().
Das Gate entscheidet, ob der aktuelle Dateizustand per
rkhunter --propupd als neue vertrauenswürdige
Referenz übernommen werden darf. Zwei Klassifizierungsregeln sind
breiter als nötig: _EXPECTED_CONFIG_RE matcht mit dem
Teilmuster [^\s:]+\.conf jede Datei mit
.conf-Endung (z. B.
/etc/cron.d/persist.conf,
/etc/ld.so.conf), und _DEVELOPER_ENV_RE
matcht bloße Substrings wie docker,
containerd oder vscode an beliebiger
Stelle im Pfad. Solche Zeilen werden als expected
eingestuft; empirisch verifiziert fällt das Gesamtrisiko dann auf
low und propupd_allowed wird
True — obwohl die betroffene Datei nicht
paketverwaltet ist und daher auch von der dpkg -V-
Gegenprüfung nicht erfasst wird.
Warum unter der Schwelle: Um eine solche Datei zu
platzieren, benötigt ein Angreifer bereits Schreibzugriff auf
/etc bzw. Systempfade — also lokale Root-Rechte.
Das Gate ist ein konservativer Sicherheits-Assistent in einem
Einzelnutzer-Desktop-Tool, keine harte Vertrauensgrenze; die
Referenzuebernahme selbst ist zusätzlich manuell, doppelt
bestätigt (askyesno) und sudo-geschützt. Es
entsteht keine Privilegien-Eskalation, sondern lediglich das Risiko,
eine bereits kompromittierte Systemdatei als „normal“ in die
Referenz aufzunehmen.
_EXPECTED_CONFIG_RE wurde von der .conf-Wildcard
auf eine explizite Whitelist bekannter Konfigurationsdateien
(rkhunter.conf, gdm3/custom.conf,
fwupd.conf, systemd/resolved.conf,
systemd/timesyncd.conf, mirrors.dat)
eingeschränkt; _DEVELOPER_ENV_RE nutzt jetzt
Wortgrenzen und Pfadsegment-Anker
((?<![\w.-])docker(?![\w.-]),
/\.devcontainer(?:/|$) …). Empirisch
gegengeprüft: /etc/cron.d/persist.conf und
…/dockerish-malware fallen jetzt in
review — das Gate schließt
(risk=medium, propupd_allowed=False) —
während legitime Fälle (/etc/rkhunter.conf,
/usr/bin/docker, .vscode/) weiterhin korrekt
als expected erkannt werden. Mit Regressionstests
abgesichert.
K2 — ClamAV-Signaturdatenbank in vorhersagbarem /tmp-Pfad
Konfidenz 2/10
Gehärtet
Datei: netmon/features/clamav_controller.py
— clamav_user_database_dir() /
clamav_database_args().
Nach einem nutzergetriebenen ClamAV-Update ohne sudo
werden die Signaturen in
<tmp>/netmon-clamav-db-<user> abgelegt und via
clamscan --database genutzt. Der Pfad ist
vorhersagbar. Auf einem gemeinsam genutzten Host könnte
ein weiterer lokaler Nutzer dieses Verzeichnis theoretisch vorbelegen
(.cvd/.cld) und so die Signaturbasis des
Opfers beeinflussen — potenziell Erkennungsschwächung.
Warum unter der Schwelle: Das Verzeichnis wird per
_safe_makedirs_no_symlink() mit 0o700
angelegt, wobei jede Pfadkomponente auf Symlinks/Nicht-Verzeichnisse
geprüft wird; ein von einem Fremdnutzer vorab angelegtes
Verzeichnis würde das mkdir scheitern lassen. NetMon
vertraut dem Verzeichnis zudem erst nach einem erfolgreichen
freshclam-Lauf. Das Zielprofil ist ein
Einzelnutzer-Desktop; ein Mehrbenutzer-Host ist untypisch.
clamscan --database prüft die neue
Funktion _clamav_database_dir_is_secure() das Verzeichnis:
es muss dem aktuellen Nutzer gehören
(st_uid == os.getuid()), darf kein Symlink sein und
keinerlei Gruppen-/Welt-Rechte tragen
(st_mode & 0o077 == 0). Empirisch
gegengeprüft: fremd-owned, gruppen-/welt-zugängliche,
symlink- und fehlende Verzeichnisse werden abgelehnt — nur ein
eigenes 0700-Verzeichnis wird als Signaturquelle
akzeptiert. Damit ist das /tmp-Vorbelegungs-Szenario
geschlossen; mit Regressionstests abgesichert.
K3 — Neue privilegierte Hilfskommandos im Scan-Worker
Kein FindingDatei: netmon/features/security_audit_controller.py
— rkhunter_scan_worker().
Der Scan-Worker führt neu sudo -n dpkg -V,
dpkg -S <pfad>,
file -b <pfad> und
sudo -n cat /var/log/rkhunter.log aus. Die
übergebenen Pfade stammen aus der rkhunter-Ausgabe
(extract_replaced_script_paths(),
extract_warning_command_paths()) — also aus
extern beeinflussbarem Text.
Bewertung: Alle Aufrufe laufen über
run_cmd(), das subprocess.run() in
Listenform ohne shell=True nutzt. Pfade werden als
einzelne argv-Elemente an dpkg -S /
file -b übergeben — keine Shell-Interpolation,
keine Option-Injection (die Werkzeuge erhalten den Pfad als
Positionsargument). Kein Command- oder Argument-Injection-Pfad.
K4 — cp -a auf die RKHunter-Referenzdatenbank
Kein Finding
Datei: netmon/core/rkhunter_manager.py
— backup_property_database() /
restore_property_database().
Beide Funktionen kopieren die rkhunter-Referenz-DB per
sudo -n cp -a. Geprüft wurde, ob der
Ziel-/Quellpfad manipuliert werden kann.
Bewertung: Beide Pfade laufen zuerst durch
_normalize_allowed_path(…, allow_prop_db=True),
das os.realpath() anwendet und ausschließlich die
zwei fest kodierten Zielpfade (rkhunter.dat und
….netmon.bak) zulässt; alles andere liefert
einen leeren String und die Operation bricht mit
„Nicht erlaubter rkhunter-Datenbankpfad“ ab. Vor der
Wiederherstellung wird zudem die Existenz des NetMon-Backups
(test -f) verlangt. Fail-closed, keine
Pfad-Traversal.
Umgesetzte Härtungsmaßnahmen (Runde 7)
Auch ohne bestätigtes ausnutzbares Finding wurden die beiden risikoreduzierenden Kandidaten direkt geschlossen — jeweils fail-closed, empirisch gegengeprüft und mit Regressionstest.
Konservativeres propupd-Gate — rkhunter_analysis_service.py
_EXPECTED_CONFIG_RE nutzt statt der .conf-
Wildcard eine explizite Whitelist bekannter Konfigurationsdateien;
_DEVELOPER_ENV_RE ist mit Wortgrenzen und
Pfadsegment-Ankern versehen. Eine nicht paketverwaltete
/etc-Änderung fällt jetzt nach
review — das Gate bleibt fail-closed
(propupd_allowed=False).
Owner-/Rechte-Prüfung der ClamAV-Signaturdatenbank — clamav_controller.py
_clamav_database_dir_is_secure() lässt
clamscan --database nur auf ein Verzeichnis zeigen,
das dem aktuellen Nutzer gehört, kein Symlink ist und keine
Gruppen-/Welt-Rechte trägt (& 0o077 == 0).
Das /tmp-Vorbelegungs-Szenario ist damit geschlossen.
Neue Regressionstests — 59 / 59 grün
test_rkhunter_analysis_service.py und
test_clamav_controller.py wurden um Tests für die
verschärfte Klassifizierung bzw. die Verzeichnis-Sicherheitsprüfung
erweitert. Alle relevanten Suiten bestehen nach den Härtungen
vollständig.
Geprüfte Sicherheitskategorien
| Kategorie | Geprüft | Ergebnis |
|---|---|---|
Command Injection (subprocess, shell=True) |
Ja | Kein Finding |
Argument Injection (Pfade aus rkhunter-Ausgabe an dpkg/file) |
Ja | Kein Finding (K3, list-form) |
Path Traversal (cp -a der Referenz-DB) |
Ja | Kein Finding (K4, fail-closed) |
Sicherheitskontroll-Umgehung (propupd-Gate zu permissiv) |
Ja | K1 → gehärtet (Whitelist) |
Signatur-/Datenbank-Vertrauen (ClamAV --database) |
Ja | K2 → gehärtet (Owner/Rechte) |
Privilegierte Kommandos (sudo -n Umfang & Argumente) |
Ja | Kein Finding |
| TOCTOU / Symlink bei Verzeichniserstellung | Ja | Kein Finding (_safe_makedirs_no_symlink) |
| Unsichere Deserialisierung (pickle, yaml.load, eval) | Ja | Kein Finding |
| Persistierte Konfiguration (Schnellscan-Pfade in Settings) | Ja | Kein Finding (normalisiert/validiert) |
| Hardcoded Credentials / API-Keys | Ja | Kein Finding |
| Sensitive Data Exposure (PII in Logs) | Ja | Kein Finding |
Auditor: Claude Fable 5 (Anthropic) —
Analyse-Sub-Agent + False-Positive-Validierung mit empirischer Reproduktion
am realen Modul
Projektverantwortlicher: Sven Fröhlich
Datum: 17. Juli 2026
Analysierter Codestand:
c2087b63 + Arbeitsstand (modified/untracked), Fokus
RKHunter-Referenzuebernahme, deterministische Analyse &
ClamAV-Datenbankwahl — Runde 7
Methode: Statische Code-Analyse + manuelle
Datenfluss-Verifikation + empirische Reproduktion des
Klassifizierer-Verhaltens + Konfidenz-gescorte FP-Validierung +
Umsetzung der beiden Härtungen mit empirischer Gegenprüfung +
Regressionstests (59/59 relevante Tests 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.