Skip to content

fix(snitchwatch): refuse rule files with invalid names in the daemon loader - #91

Closed
bearyjd wants to merge 1 commit into
build/snitchwatch-r11-repinfrom
fix/snitchwatch-daemon-load-rule-names
Closed

bearyjd wants to merge 1 commit into
build/snitchwatch-r11-repinfrom
fix/snitchwatch-daemon-load-rule-names

Conversation

@bearyjd

@bearyjd bearyjd commented Oct 8, 2026

Copy link
Copy Markdown
Owner

Stacked on #90. Hardening found by Snitchwatch's security review of its #108 bridge mapping. The OpenSnitch patch grows from 49 to 50 files, sha256 b49df450….

Problem

The daemon ran ValidName on every UI path (Add/Replace/delete/Deserialize), but not in loadRule, which reads rule files from /etc/opensnitchd/rules at startup and on fsnotify live reload. A root-written file named "" would load, and could pose as the #89 synthetic default-action rule that the bridge keys on (name "" plus description snitchwatch:default-action).

Change

  • loadRule refuses a rule whose name fails ValidName, before compile, insert or monitor start. It logs a warning with the file name (%q) and leaves the file on disk.
  • On live reload, a now-invalid file for an existing valid rule leaves the old rule loaded until the next restart. That's fail-safe and matches upstream's handling of parse and compile errors.
  • New test file rule/loader_name_validation_test.go: "", a/b, a newline, ., a backslash and 201 bytes are refused at Load and on live reload, and valid files still load. Both tests fail with the check removed.

Review

Code review: APPROVE. Its LOW follow-ups:

  • a test that overwrites a valid rule with an invalid name;
  • .. / U+202E cases on the live path;
  • a 1 s watcher sleep in the test;
  • the refusal is logged twice, inside loadRule and by its callers.

Test plan

  • just test-snitchwatch-daemon-patch: PASS. The first run hit an upstream flake in the non-race ./ui pass: TestClient* reloads the firewall config, and iptables.Init dereferences nil when nftables isn't permitted and iptables is missing. The re-run passed; the ui package is untouched by this change.
  • Python suites (50 patched files); just check
  • r12 VM: a root-written "" rule file is refused
  • CI green

…loader

The daemon validated rule names on every UI path but not when loading rule
files from disk, at startup or on live reload, so a root-written file named
"" could pose as the synthetic default-action rule that the Snitchwatch
bridge keys on (name "" + description "snitchwatch:default-action").
loadRule now refuses a name that fails ValidName, logs the file and leaves
it on disk. The OpenSnitch patch grows to 50 files (new loader test).
Found by Snitchwatch's security review of its #108 bridge mapping.
@bearyjd

bearyjd commented Oct 9, 2026

Copy link
Copy Markdown
Owner Author

Included via #92 (merge commit af32644): this PR's commits are in main as part of the stacked merge; the r12 image was VM-accepted at 21adea3.

@bearyjd bearyjd closed this Oct 9, 2026
@bearyjd
bearyjd deleted the fix/snitchwatch-daemon-load-rule-names branch October 10, 2026 15:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant