From f9bb02707f5f4e34a2d0cc3e16605a094c575058 Mon Sep 17 00:00:00 2001 From: kisfenyo Date: Mon, 12 Oct 2026 17:21:11 +0200 Subject: [PATCH] security review: STATUS (four decisions) and REPORT-security-review-2026-10-12.md --- REPORT-security-review-2026-10-12.md | 97 ++++++++++++++++++++++++++++ STATUS.md | 27 ++++++++ 2 files changed, 124 insertions(+) create mode 100644 REPORT-security-review-2026-10-12.md diff --git a/REPORT-security-review-2026-10-12.md b/REPORT-security-review-2026-10-12.md new file mode 100644 index 00000000..458bc3b9 --- /dev/null +++ b/REPORT-security-review-2026-10-12.md @@ -0,0 +1,97 @@ +# REPORT — security review 2026-10-12, parts 1 and 2 + +Written as `REPORT-.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`). diff --git a/STATUS.md b/STATUS.md index fd9de358..d601085e 100644 --- a/STATUS.md +++ b/STATUS.md @@ -5,6 +5,33 @@ **Updated 2026-10-12 (your 38 answers): hub 0.147.0; demo-hp, demo-felhom and Tester 1 run agent 0.154.0 and controller 0.308.0. The open-items list is at 97 (2026-10-12: your 38 answers, 32 closed, 1 opened). Reports: `REPORT-answers-2026-10-12.md`, `REPORT-m3-2026-10-11.md`, `REPORT-redesign-2026-10-10.md`, `REPORT-testers-2026-10-10.md`, `REPORT-register-shrink-2026-10-10.md`, `REPORT-new-apps-2026-10-10.md`, `REPORT-release-2026-10-10.md`, `REPORT-break-the-circle-2026-10-09.md`, `REPORT-dooplex-survival-2026-10-09.md`, `REPORT-day4-2026-10-09.md`.** +## Monday 2026-10-12 (evening): security review — the hub is closed again; four decisions for you + +- **The hub's old master key is dead.** It was in public git history and still worked. Changed today with your yes; + the old key is now refused. All three boxes kept reporting. +- **The open hub page is closed.** Hub 0.148.0 is live: the customer list and box reports now need the master key. + Tested, red-proved, and checked on the live hub. +- **We cannot tell if a stranger used either hole before today.** The logs only go back to this morning (and one day + in June). The holes were open since February — about 238 days we cannot see. Decision 1 below. +- **One box cannot read another box's data on the hub** — checked in the code and with tests (5 new ones). +- **The review found 18 more things to fix** (3 serious, the rest medium or small). Each is a row; the next tasks are + ranked in `documentation/audits/security-review-2026-10-12/FINDINGS.md`. The papers do not say how to use an open hole. +- **A gate test wrote into the shared repository** while this session pushed from a separate copy: it put the name „d" + on two of another session's commits and was probably what flipped `core.bare` (R-935). Fixed by hand; noted on R-935. + +**Waiting on you:** +- Put the new hub master key into your password manager (entry „Felhom hub global bearer (report_api_key)") from + `/mnt/5_hdd/felhom.eu/evidence/security-review-2026-10-12-PRIVATE/new.key`, then `shred -u` that file. + +**Your four decisions** — the question, **my pick**, what the other option costs, what happens if you do nothing: + +| # | Row | Question | Pick | The other option | If you do nothing | +|---|---|---|---|---|---| +| D1 | R-954 | Change the break-glass root password of every box now, because we cannot see if the old key was used? | **Yes, change them** (Tester 1 holds a real person's data; ep0 holds copies) — about one hour, one box at a time, through the existing vault | Accept: no work, but a password that may have been read stays valid on every box | the old root passwords stay; if they were read, they still open the boxes from the LAN or console | +| D2 | R-971 | Should the box refuse a catalog change that asks for dangerous container rights (privileged mode, the Docker socket, host mounts)? | **Yes — an allow-list on the box** (one controller release; the few apps that need a right are listed) | Keep trusting the catalog repository: no work, but whoever can push to it reaches every box | a catalog push keeps reaching every box's apps with no check | +| D3 | R-985 | Our „zero-knowledge" promise: change the wording, or remove the operator's root reach to the backup key on a live box? | **Change the wording now** („we cannot read your off-site backup without you — except on a live box, where we hold the break-glass key"); revisit after the first sale | Remove the reach: a design change to break-glass | the promise stays stronger than the product | +| D4 | R-982 | Should root log in over SSH with a password from the LAN? | **No — key only**; the password stays for the console | Keep it: nothing to do, anyone on the household network can try the password | the host keeps accepting root password logins from the LAN | + ## Monday 2026-10-12 (afternoon): your 38 answers — built, released and delivered (Parts A–G); the list from 128 to 97 - **All 38 answers are written down** (decisions 196–233). Your words won where they differed (S1, S2, S8, S32, S37).