Files
felhom.eu/REPORT-security-review-2026-10-12.md
T
2026-10-12 17:21:11 +02:00

5.9 KiB
Raw Blame History

REPORT — security review 2026-10-12, parts 1 and 2

Written as REPORT-<topic>.md, not REPORT.md: other sessions worked in this repository at the same time (CLAUDE.md, „two sessions clobber each other").

In plain language

  • Is the hub closed now? Yes. The old master key is dead (rotated with your yes). The open customer page needs the master key since hub 0.148.0, which is live and checked.
  • Did anyone use the holes? Cannot tell. The logs cover only 2026-10-12 from about 09:54, and one day in June. The holes were open since February 2026 — about 238 days that no log shows.
  • You must decide four things (STATUS.md, D1–D4): change every box's root password (my pick: yes); a box-side check on catalog changes (my pick: yes); the zero-knowledge wording (my pick: change it now); root password SSH from the LAN (my pick: key only).
  • Next tasks, in order: R-954 (your decision) → R-970 (remove the box's settings-file route) → R-972 (patched Go and base images) → R-971 (catalog check) → R-952 (hub route guard test) → R-953 (ArgoCD prune danger) → the medium rows.

What did not go as written

  • The safety filter stopped this session three times — while writing the first findings table, the hub route-guard test (Scenario D), and the Part 2 log search. As the operator ruled, each became short register rows: R-952 (route guard), R-954 (the log question). The detailed working notes are off-git: /mnt/5_hdd/felhom.eu/evidence/security-review-2026-10-12-PRIVATE/.
  • The live cross-box GETs (Part 3) were not run. The source and unit tests answer the question; the live check is in R-955.
  • One red-proof, not five, for the new cross-box tests (R-955).
  • A gate test wrote into the shared repository when this session pushed from a git worktree: four test commits in the worktree and user.name d in the shared .git/config (two other-session commits carry that author). The session removed the [user] section, stopped pushing from the worktree, and pushed from a normal clone instead. Noted on R-935 (the core.bare flips another session filed).
  • Register ids R-934/R-935 collided with another session; this session's rows moved to R-950–R-955 and R-970–R-987.

Baselines

felhom.eu 0d463a85 at the start of part 2 (hub 0.147.0 live, no unreleased hub code after its release commit 655f5f66); controller dcd89364a4; agent 86adbcaf8a. ArgoCD: the hub was Synced; three Secrets and Deployment/umami OutOfSync (R-953).

Release — hub v0.148.0

  • Commits: b67b8cea (code), 8d34d607 (manifest). Built from a clean clone at b67b8cea (the shared clone held another session's unpushed commit, so the build script's own pull could not run; the script was used unchanged except for the source folder).
  • ArgoCD: a sync of Deployment/hub only, no prune; operation Succeeded at 8d34d607. Image gitea.dooplex.hu/admin/felhom-hub:0.148.0, pod Ready. The three Secrets are still present.
  • Live check (audits/security-review-2026-10-12/evidence/hub-0.148.0-live-check.txt): no credential → 403 on all three routes, no customer in the body; the master key → 200.
  • All three boxes reported after the restart (controller and agent reports), 0 auth failures in the hub log.

Tests

  • TestCustomersRoutes_NoCredentialIsRefused, …_BoxKeysAreRefused, …_GlobalKeyUnchanged — pass. Red-proof: with the check removed from handleCustomer, the first failed (GET /customers/c1 answered 200).
  • Five cross-box tests (crossbox_refusal_test.go) — pass. Red-proof on the restore-directive test: with its host check disabled it failed (another box's key got 200). The first try was masked by a later check; the test now arms recovery mode so only the host check can refuse.
  • Hub test functions: 1079 before → 1087 after. Green gate: go build, go vet, go test ./... in hub/ pass.

Part 2 — logs

log oldest line it holds
ingress-nginx controller, rotated files on DooPlex one file 2026-06-10 08:08–16:44; then 2026-10-12 09:54 onward
hub pod log only the current pod (2026-10-12 ~16:57 onward); older pods' logs are gone
central log store none exists on DooPlex
Cloudflare none: hub.felhom.eu is not proxied by Cloudflare

The search for strange addresses was not completed (see above). Blind window: from 2026-02-16 (the key's first commit) to 2026-10-12 09:54 — about 238 days. FILED: R-954.

Register

Rows before this part: 97. After: 119. Opened: 22 open (R-952–R-955, R-970–R-987) plus 2 born closed (R-950, R-951, in CLOSED-ITEMS.md). Closed: 2. Noted: R-935, R-132, R-908. (Other sessions also changed the register today; these numbers count this session's rows.)

Observations

  • Hub key exposure — FILED: R-950 (closed, rotated).
  • Open customer routes — FILED: R-951 (closed, hub 0.148.0).
  • Route guard missing — FILED: R-952.
  • ArgoCD would prune live Secrets — FILED: R-953.
  • Exposure window not visible — FILED: R-954.
  • Cross-box check not fully proven — FILED: R-955.
  • Part 1 findings — FILED: R-970 to R-987 (see FINDINGS.md).
  • Gate test writes into the real repo from a worktree — NOT-A-FINDING here: a note on R-935, which owns it.
  • Hub login hash in the public manifest — NOT-A-FINDING here: a note on R-132.
  • gitleaks misses R-908's key — NOT-A-FINDING here: a note on R-908 and input to R-986.
  • Old registry token and old Resend key in history — NOT-A-FINDING: both rotated (checked by hash / last eight characters).
  • System poster: no fact in felhom-system-poster.facts.md changed.

Teardown

Machines: nothing provisioned; demo-hp was only read. Host: none. Hub: one release (0.148.0) and the key rotation; no other change. DooPlex files: the private evidence folder, the scanner tools under /mnt/5_hdd/felhom.eu/tools/security/, the git worktree and clone under /mnt/5_hdd/felhom.eu/wt/, and a copy of the build script (build/felhom-hub/build-0.148.0-from-clean-clone.sh).