Security app updates, Part 1: the triage of 38 flagged pins (TRIAGE.md, per-app notes, PICKS.md); R-1306 triaged; R-1310 (watch classifier) and R-1311 (Termix X-Forwarded-For) filed
gates / gates (push) Successful in 2m0s
gates / gates (push) Successful in 2m0s
This commit is contained in:
1 parent
c6248dbfc5
commit
ba06b873b9
36 files changed
+903
-3
No files matched your search
@@ -0,0 +1,49 @@
|
||||
# Picks for the operator — flaws with no fix inside the main version (2026-10-27)
|
||||
|
||||
No template was changed for any of these. Each pick: the question, CC's pick first, the cost of the other, and what
|
||||
happens if nobody decides. Fleet fact for all of them (hub 2026-10-27): **no box runs any of these apps**; the risk is a
|
||||
NEW install.
|
||||
|
||||
## 1. SparkyFitness — two notices, no fix released (GHSA-p8cf-g8rv-gvrq, GHSA-cmmf-53wf-r5gv)
|
||||
|
||||
What a stranger can do with our template: nothing without an account or a leaked photo URL. p8cf needs a household
|
||||
account (it overwrites another member's Withings link); cmmf needs the exact URL of an owner-only photo. A third notice
|
||||
(GHSA-v883) does not apply: our template generates `BETTER_AUTH_SECRET` per install.
|
||||
|
||||
- **A (CC's pick): leave it offered and wait for the upstream fix**, then take it with R-785's big step (0.17 → 1.x).
|
||||
Cost: a family that installs it meanwhile carries two medium flaws that need one of its own accounts.
|
||||
- **B: hide it from new installs** (`lifecycle: hidden`) until a fixed version is proven. Cost: the app disappears from
|
||||
the catalog for an unknown time.
|
||||
- **If you do nothing:** A.
|
||||
|
||||
## 2. Gitea — GHSA-rqhx-647v-wx32: SSRF through a redirect in repository migration (the upstream patch was reverted)
|
||||
|
||||
What a stranger can do: nothing without an account (sign-up is closed twice in our template). A household account can
|
||||
make the box fetch an internal address through „New migration".
|
||||
|
||||
- **A (CC's pick): leave migrations on**, and judge it again in Gitea's big step (1.27.3 → 28.2.0, which fixes 40 other
|
||||
notices). Cost: a signed-in household member can reach the home network through the migration form.
|
||||
- **B: turn migrations off** (`GITEA__repository__DISABLE_MIGRATIONS=true`). Cost: the household cannot import a
|
||||
repository from GitHub any more.
|
||||
- **If you do nothing:** A.
|
||||
|
||||
## 3. Termix — GHSA-7j7m-85p4-2cpm: a stranger skips the login rate limit with a forged X-Forwarded-For (R-1311)
|
||||
|
||||
The fix is Termix's big step (2.8 → 2.9.2 → 26.10.5, two hops).
|
||||
|
||||
- **A (CC's pick): wait for the big step.** Cost: until then, a stranger can guess passwords faster than the limit means.
|
||||
- **B: strip the header in the template now** (as docmost and paperless do, R-753). Cost: every visitor then shares the
|
||||
tunnel's one address, so a stranger's wrong guesses can lock the household out of the login (the Grimmory shape,
|
||||
R-775).
|
||||
- **If you do nothing:** A.
|
||||
|
||||
## 4. The big steps a stranger can use before they are done (Wanderer, Jellyfin, Gitea, Termix)
|
||||
|
||||
Wanderer's critical notice (GHSA-fprh-3pp9-68m9: any remote ActivityPub server overwrites records, no login, federation
|
||||
has no off switch) is the worst open item. Jellyfin (GHSA-hw73, a file read with no login), Gitea (two notices with no
|
||||
login) and Termix (above) follow.
|
||||
|
||||
- **A (CC's pick): hide Wanderer from new installs** (`lifecycle: hidden`) until its big step (v0.21.2) is proven; leave
|
||||
the others offered. Cost: Wanderer leaves the catalog for the days its step takes.
|
||||
- **B: leave all four offered.** Cost: a new Wanderer install is open to any federated server from its first day.
|
||||
- **If you do nothing:** B.
|
||||
@@ -0,0 +1,94 @@
|
||||
# Security app updates — the triage (2026-10-27)
|
||||
|
||||
Input: the security watch run WITH the GitHub key (local dry run 2026-10-27 ~07:50 UTC, the same code as CI job 2415):
|
||||
**38 pins with open notices — 3 box programs and 35 app pins in 32 apps** (the seed's 30 pins were a no-key half; the
|
||||
key read every repo). Each app was read by hand: every GHSA in full, every release body between our pin and the fix,
|
||||
our template's gates and env. Per-app notes, with the tags and ids read: `triage-notes/<app>.md` (four read-only helper
|
||||
sessions, brief `triage-notes/_HELPER-BRIEF.md`, the fences in full; checked and merged by CC).
|
||||
|
||||
**Fleet today (hub `/apps`, 24 h):** four controllers report — Tester 1, demo-hp, demo-felhom, Tester4 — no household.
|
||||
Of the 32 apps only BookStack, Paperless-ngx, PrivateBin, BentoPDF, Docmost, Home Assistant and RomM run on any box.
|
||||
|
||||
**How a box is exposed:** every app has a public HTTPS name through the tunnel. `setup_gate` closes it to strangers
|
||||
only until the first admin exists; `family_gate` keeps it behind the household door for good; `signup_block` refuses
|
||||
the public sign-up path. „Main version" = the first number (the project's `major_of`); a step inside it goes by the
|
||||
lane only when the notes between pin and target show no file conversion, no new required setting and no removed option.
|
||||
|
||||
## Lane A — same main version: a `security_fix` step (Part 2)
|
||||
|
||||
| # | App | Pin → TARGET | Real / total | Worst real (login?) | Reachable on a box | Id(s) the step carries | Fixture | State |
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
| 1 | rallly | 4.15.3 → 4.16.3 | 1+3 rel / 1+4 | critical RCE (none) | yes, after setup | GHSA-gmq4-f8j5-8w8q | yes | pending |
|
||||
| 2 | romm | 5.3.1 → 5.4.1 | 6 / 6 | high: unauth WebSocket scan deletes media (none) | yes | GHSA-722m-w9p2-xv2j, -q7fg-…, -7jw3-…, -9q83-… | yes | pending |
|
||||
| 3 | code-server | 4.129.0 → 4.143.1 (lscr.io) | 1 / 1 | high: Node Brotli before sign-in (none, inferred) | yes, no gate | CVE-2026-111497 (Node Oct 2026) | no (seed none) | pending |
|
||||
| 4 | outline | 1.10.1 → 1.12.0 | 8 / 13 | high: unpublished doc keeps its share (none) | yes | GHSA-rq53-m97j-f2pg, -97vv-…, -w8vg-… | yes | pending |
|
||||
| 5 | vikunja | 2.6.0 → 2.7.1 | 42 / 45 | high (any user; m687 needs the victim's browser) | own login (setup+signup gates) | GHSA-m687-p538-r5hp, -hq66-…, -5q33-… | yes | pending |
|
||||
| 6 | homebox | 0.26.2 → 0.27.1 | 14 / 15 | high: group takeover (any user) | own login; unauth register notices blocked by signup_block | GHSA-jm28-2xm3-m6m5 … | yes | pending |
|
||||
| 7 | n8n | 2.42.1 → 2.44.7 | 12 / 13 | high (a workflow builder) | own login | GHSA-m7gv-…, -mp7q-…, -wvjj-… | yes | pending |
|
||||
| 8 | privatebin | 2.0.6 → 2.1.0 | 2 / 2 | medium: fake pop-up (none) | yes, public by design | GHSA-w873-3ghv-hmh6 | yes | pending |
|
||||
| 9 | docmost | 0.96.0 → 0.97.0 | 1 rel / 1 | unsure: Node 26 + fastify/socket.io (pre-auth surfaces) | yes, after setup | CVE-2026-111497 (Node Oct 2026) | yes | pending |
|
||||
| 10 | grafana | 13.2.3 → 13.2.4 | 1 rel / 5 | medium: CVE-2026-15577 (read-only user) | own login | CVE-2026-15577 | yes | pending |
|
||||
| 11 | mealie | v3.28.0 → v3.29.0 | 1 / 1 | medium (any user, 2+ groups) | own login | GHSA-99wf-32rc-2767 | yes | pending |
|
||||
| 12 | audiobookshelf | 2.37.1 → 2.37.2 | 1 rel / 1 | Node runtime; low in practice | own login | CVE-2026-111497 (Node Oct 2026) | yes | pending |
|
||||
| 13 | bentopdf | v2.8.6 → v2.8.10 | 1+2 rel / 3+2 | low known (cx8x, a crafted workflow file); v2.8.10's two GHSAs still private | yes, no login by design | GHSA-cx8x-7rrr-r9x8, -v77x-…, -qch9-… | no (seed none) | pending |
|
||||
| 14 | uptime-kuma | 2.5.5 → 2.5.8 | 1 rel / 2+3 | admin-only code execution (GHSA-v2p3, unpublished) | admin login | GHSA-v2p3-6f5h-6hhf | yes | pending — CAVEAT: 2.5.8 drops TLS on the TCP-port monitor |
|
||||
| 15 | immich | v3.2.4 → v3.3.5 (server + ml) | 0 GHSA + 1 rel | Node + CA bundle runtime only | own login | CVE-2026-111497 (Node Oct 2026) | yes | optional — lowest |
|
||||
|
||||
## Lane A′ — same main version but NOT the lane
|
||||
|
||||
| App | Pin → TARGET | Why not the lane | Path |
|
||||
|---|---|---|---|
|
||||
| wishlist | v0.67.1 → v0.69.0 | **critical, no login**: `/forgot-password` returns the reset token in its own response, SMTP or not (PR #818) — but **no GHSA/CVE is published**, and the lane's authority is a public notice id | a NORMAL proven step: bench (fixture exists) + box walk, `--write-ladder` |
|
||||
| bookstack | 26.09.1 → 26.09.2 (lscr.io) | a real security release (two authorisation leaks between signed-in users) with **no CVE/GHSA id** | a normal proven step (fixture exists), after the lane batch |
|
||||
|
||||
## Lane B — a new main version, or a breaking change inside it (Part 3)
|
||||
|
||||
| App | Pin → TARGET | Worst real (login?) | Why big | Runs on a box today |
|
||||
|---|---|---|---|---|
|
||||
| wanderer | v0.20.0 → v0.21.2 (web + db) | **critical: any remote ActivityPub server overwrites records (none)**; federation has no off switch | new REQUIRED `POCKETBASE_PROXY_SECRET` on both services; 0.21.1 migration shortens rich text, no downgrade | no |
|
||||
| jellyfin | 10.11.11 → 12.4 | critical 6828 (admin after setup); hw73 file read with **no login** (medium) | 10 → 12; DB conversion with no rollback; `/emby` + legacy auth removed | no |
|
||||
| gokapi | v1.9.6 → v2.2.4 | high 3c22 is self-XSS for the only account | 1 → 2; user system, no downgrade; our first-boot config seed must be re-captured | no |
|
||||
| seerr | jellyseerr 2.7.3 → `ghcr.io/seerr-team/seerr:v3.5.1` | high rc4w (stranger registers, Plex setups only), mc6w path traversal → RCE (needs a hostile media server) | 2 → 3; new image name; runs as UID 1000 → `/app/config` chown; config migration | no |
|
||||
| karakeep | 0.33.2 + chrome 151 → 0.34.1 + chrome 154.0.8037.57-r1 | high: two CISA-KEV V8 bugs in the crawler's Chromium (`--no-sandbox`), via content the household saves | auth library swap (everyone signed out, e-mails lowercased); chrome rebuilt on full Chrome — memory limit and healthcheck to re-measure | no |
|
||||
| gitea | 1.27.3 → 28.2.0 | critical 7cq7 / 6pv5 (any user); c3cr, hf55 need no login | 1.28 renamed 28.0.0 — no 1.27.4 exists; 28.0 routes git traffic through a new proxy with egress settings | no |
|
||||
| paperless-ngx | 2.20.15 → 3.3.4 | low (2jhj, needs a setting we do not set) — **not reachable** | 2 → 3: encryption + API v1 removed, search index rebuilt | YES (4 test boxes) — not urgent |
|
||||
| homepage | v1.13.2 → v2.7.0 | medium; family_gate, only with a hand-written credentialed widget | 1 → 2: auth rework | no |
|
||||
| termix | 2.8.0 → 2.9.2 → 26.10.5 | high; **7j7m: the login rate limit is bypassed by a spoofed X-Forwarded-For (no login)** | two hops (2.9 must start once); calendar versions; guacd dropped | no |
|
||||
| tandoor | 2.6.15 → 2.7.2 | high: 5f74 XXE file read, 69q3 (any user) | 2.7.0 removes settings and an endpoint and rewrites the login pages (our probe path, unsure); 2.7.0/2.7.1 break invite links with sign-up off → straight to 2.7.2 | no |
|
||||
| sparkyfitness | v0.17.3 (both images) | medium p8cf (any user), cmmf (a leaked photo URL) | **no fix named in any release**; 0.17 → 1.x is R-785's big step anyway | no |
|
||||
|
||||
## No fix exists (Part 4)
|
||||
|
||||
| App | Notice | What blocks it in our template | Pick |
|
||||
|---|---|---|---|
|
||||
| sparkyfitness | GHSA-p8cf-g8rv-gvrq (a user overwrites another user's Withings link), GHSA-cmmf-53wf-r5gv (owner-only photos readable by URL) | own login (any household account); cmmf needs the full photo URL | see `PICKS.md` |
|
||||
| gitea | GHSA-rqhx-647v-wx32 (SSRF through a redirect in repository migration; the upstream patch was reverted) | own login; migrations are on by default | see `PICKS.md` |
|
||||
| karakeep, bentopdf | — | the watch said „no fixed version"; fixes exist (karakeep-chrome 154/156; bentopdf's two are in the Cloudflare CORS-proxy worker we neither ship nor deploy) | none needed |
|
||||
|
||||
## NOT-A-FINDING
|
||||
|
||||
| App / notice | Reason |
|
||||
|---|---|
|
||||
| calcom GHSA-p3f6-52gv-cj7m | the project's own GitHub workflow (2024), not the product |
|
||||
| calcom GHSA-cpf2-q635-xrwx | range is the hosted service / ≤ 3.1.4 (2023); our pin v6.2.0 |
|
||||
| home-assistant GHSA-jff5-5j3g-vhqc | a GitHub Actions advisory (ecosystem `actions`) of the project's CI, fixed 2023 |
|
||||
| glance GHSA-r225-jhr6-68cc | only when Glance's own login is configured; our seeded config sets none, and family_gate stands in front |
|
||||
| dawarich release 1.17.0 | the hit is „Node 20 … no longer receives security fixes" — a maintenance swap, not a fix (1.16.0 carries two hardening fixes the watch missed — optional) |
|
||||
| immich GHSA-8244-8vpr-vp9c | the range is untagged `main@<sha>` builds; the fix commit is already inside v3.2.4 |
|
||||
| grafana four GHSAs of 2022/2023 | fixed in Grafana 7.5 / 8.x / 9.x years ago; malformed ranges |
|
||||
| uptime-kuma GHSA-98hr, GHSA-qjxc | rootless image only (we run the normal one); a cloud-metadata issue the project closed as won't-fix |
|
||||
| outline 5 SSO / GitLab / cross-team notices | our template configures no SSO and no GitLab integration (e-mail link + passkey) |
|
||||
| vikunja 3 notices | the xgo release toolchain; the Trello/Todoist/MS To Do migrators (off) |
|
||||
| gitea GHSA-x4q3-gcj3-m6cf | the package is the Actions runner, which we do not ship |
|
||||
| termix GHSA-frx8, GHSA-r9gw | the Electron desktop client, which we do not ship |
|
||||
| paperless-ngx GHSA-c8f3 | range 3.0–3.3.2; we run 2.20.15 |
|
||||
| n8n GHSA-365g-vjw2-grx8 | Execute Command is left out by default in 2.x, and our compose keeps that default |
|
||||
| wishlist v0.68.0 nodemailer (GHSA-6vj9-mwq6-2f5v) | needs several SMTPS transports in one process; one transport, and we set no SMTP |
|
||||
|
||||
## Box programs (Part 5)
|
||||
|
||||
| Program | Pin → TARGET | Real | Breaking (notes read) |
|
||||
|---|---|---|---|
|
||||
| traefik | v3.7.13 → v3.7.16 | 12 notices; none reaches our config (docker + file providers, no FastProxy, no NTLM backend, no k8s) — R-1304 | migration guide v3.7.14–16: k8s providers' names, OTel histograms, **CONNECT rejected with 501**; none touches us |
|
||||
| file manager | 1.5.6-stable → **1.5.8-stable** | GHSA-qx86-4v5r-26g5 (TOTP re-enrol), GHSA-3846-gh75-gp3m (upload share) — R-1305 | 1.5.7-stable is superseded: it broke existing TOTP logins; 1.5.8-stable supersedes it |
|
||||
| cloudflared | 2026.10.3 → 2026.10.4 | VULN-176088 „Allowlist debug endpoints on the metrics server"; our metrics port is not reachable from outside — low | none |
|
||||
@@ -0,0 +1,61 @@
|
||||
# Triage brief for a helper (read-only)
|
||||
|
||||
## Fences — the brief's own, in full (you need almost none of them, but you carry them all)
|
||||
- Forbidden: any ep0 change; any DooPlex change except the catalog push after its STOP (you make NO push and NO commit);
|
||||
a household box by hand; a `security_fix` step for a major version jump; turning off a check to make a test pass.
|
||||
- No test traffic on demo-hp (its host or any guest: 9202, the bench 9401, Tester 1) until the line test has finished.
|
||||
YOU touch no machine at all: no ssh, no pct, no docker, no curl/POST to any box, hub, Gitea or registry write.
|
||||
- Rules: secrets never printed or committed; no ep0 change; no branches; no commits; every finding a row, a fix or
|
||||
`NOT-A-FINDING: <reason>`. Never `docker system prune` or any Docker cleanup. Stay inside /mnt/5_hdd/felhom.eu/ and the
|
||||
scratchpad. Reading the web (GitHub pages, release notes, vendor docs) is allowed.
|
||||
- Your job is READ and WRITE NOTES ONLY, into the scratchpad paths named below. Do not edit any repo file.
|
||||
|
||||
## Context
|
||||
Felhom is a managed home server. Each catalog app runs from `app-catalog-felhom.eu/templates/<app>/` (docker-compose.yml
|
||||
+ .felhom.yml). Last night a security watch listed upstream security notices for our pinned versions. You sort them.
|
||||
Per app the data is in `<scratchpad>/tri/apps/<app>/data.json`: our pins, every GHSA notice in full (description, vulnerable
|
||||
ranges in `vulns`, severity), and up to 60 recent GitHub releases (tag, date, body). Also `<scratchpad>/tri/items.json` (the
|
||||
watch's own view, one item per pin, field `advisories`, including release-note hits whose id starts `release:`).
|
||||
|
||||
Exposure on a Felhom box: EVERY app gets a public HTTPS subdomain through a Cloudflare tunnel, so it is reachable from
|
||||
the internet. Three template fields narrow that (read them in .felhom.yml):
|
||||
- `family_gate: true` — a permanent door: only a household member signed in to the household gate reaches the app at all.
|
||||
- `setup_gate: true` — closed to strangers ONLY until the first admin is created; after that the app is public behind its
|
||||
own login.
|
||||
- `signup_block:` — traefik refuses the app's public sign-up path (strangers cannot create an account).
|
||||
No gate field = the app's own login is the only door (or none). Some apps also have optional features off by default
|
||||
(SSO, federation, mail import...): read the compose env to see whether a vulnerable feature is on in OUR template.
|
||||
|
||||
"Main version" = the FIRST number of the version (project rule; 0.20 -> 0.21 is the same main version 0). A step inside
|
||||
the main version may go by the quick "security fix" lane ONLY if the release notes between our pin and the target show
|
||||
no data conversion / migration of files, no removed config, no breaking change. Database schema migrations that the app
|
||||
runs itself on start are normal and fine; a FILE layout change, a required manual step, a changed env var name, a new
|
||||
required service, or a database ENGINE major change (postgres 15 -> 16 etc.) is NOT fine for the quick lane.
|
||||
|
||||
## What to decide per app
|
||||
1. Each notice: REAL (it affects our pinned version, per its ranges or by reading) or NOT-A-FINDING + one-line reason
|
||||
(e.g. "affects only the desktop client we do not ship", "range ends below our pin", "it is about the project's own CI
|
||||
workflow, not the product", "a release-note hit that only mentions the word security"). For `release:` hits read the
|
||||
release body itself: is it a real security fix of the app (or of its runtime, e.g. Node.js security release bundled in
|
||||
the image)? Say which.
|
||||
2. For each REAL notice: severity; needs a login? (none / any user / admin); reachable on a Felhom box with OUR template
|
||||
(consider the gates above and whether the vulnerable feature is enabled in our compose).
|
||||
3. The fix: the SMALLEST released version that fixes every real notice; and the recommended TARGET = the newest stable
|
||||
release in the same main version that is >= that fix (stable only, no rc/beta). Give the exact image tag as it would
|
||||
appear in our compose (match our tag style: `v` prefix or not — check the registry tag naming from our current pin).
|
||||
If the app has TWO+ images (e.g. web + db, server + ml), give each one's target.
|
||||
4. Main version same? yes/no. Breaking changes / migrations between our pin and the target, read from the release notes
|
||||
(list them, or "none found" with how many releases you read).
|
||||
5. Lane: SECURITY_FIX (same main version, nothing breaking) / BIG_STEP (new main version, or breaking changes) /
|
||||
NO_FIX (a real notice with no fixed release) / NOT_A_FINDING (nothing real). An app can have both (e.g. SECURITY_FIX
|
||||
for some notices + NO_FIX for one) — say so.
|
||||
6. A note for the watch's classifier if it flagged something it should not (one line, concrete), else "none".
|
||||
7. For NO_FIX notices: what in our template would block it (gate, feature off), and 2 options for the operator with
|
||||
the cost and "if you do nothing".
|
||||
|
||||
## Output
|
||||
Write `<scratchpad>/tri/apps/<app>/triage.md` per app (plain, compact; cite the release tags and GHSA ids you read). Then reply
|
||||
with ONE markdown table, one row per app, columns:
|
||||
| app | our pin(s) | real / total notices | worst real severity | login needed | reachable on a box | smallest fix | TARGET tag(s) | same main | breaking changes | lane | classifier note |
|
||||
Keep the reply under 900 words. Be exact; when unsure, say "unsure: <why>" — never guess a version tag (check the
|
||||
release list / registry tag pages).
|
||||
@@ -0,0 +1,19 @@
|
||||
# audiobookshelf — triage (group D)
|
||||
Pin: ghcr.io/advplyr/audiobookshelf:2.37.1. Gates: setup_gate (public behind own login after the first admin).
|
||||
|
||||
## Notice: release:advplyr/audiobookshelf@v2.37.2 "October 2026 security release" — REAL, runtime only
|
||||
Body of v2.37.2: "Docker image rebuilt with Node.js 24.22.1 (October 2026 security release)". The image is
|
||||
FROM node:24-alpine (Node 24 since v2.37.0), so 2.37.1 carries a Node 24 older than 24.22.1 -> affected by the Oct 2026
|
||||
Node CVEs (Brotli OOB write high; TLS hostname/DNS client issues).
|
||||
- Reach in this app: no known path. express ^4 (body-parser 1.x inflates gzip/deflate only, not br); axios ^0.27.2
|
||||
(no brotli). Other CVEs are client-side TLS/DNS: reached only when a logged-in user makes the server fetch
|
||||
(podcast feed, metadata match). App code fixes in 2.37.2 are bug fixes; "Server init rejects creating a second root
|
||||
user" is listed as internal hardening.
|
||||
- Severity: high per Node; practical here: low (unsure: no audit of every fetch path). Login: any user for fetch paths.
|
||||
Reachable: only via a logged-in user.
|
||||
|
||||
## Fix / target
|
||||
Smallest fix = TARGET: `ghcr.io/advplyr/audiobookshelf:2.37.2` (ghcr tag exists; no `v`, matches pin). Same main: yes (2).
|
||||
Breaking: none found (read 2.37.2). `ROUTER_BASE_PATH` normalization — not set in our compose.
|
||||
Lane: SECURITY_FIX.
|
||||
Classifier note: none (summary text "1 (October 2026 security release)" is a fragment but the hit is right).
|
||||
@@ -0,0 +1,17 @@
|
||||
# bentopdf — triage (group C, 2026-10-27)
|
||||
Pin: ghcr.io/alam00000/bentopdf:v2.8.6 (static nginx bundle, all PDF work in the browser). No gate field, no login. The Cloudflare CORS-proxy worker (`cloudflare/cors-proxy-worker.js`) is a separate Worker deployed to Cloudflare; it is not in our image and our compose sets no VITE_CORS_PROXY_URL.
|
||||
|
||||
## Notices (3 + 2 release hits)
|
||||
- GHSA-wh78-rcw2-hhg9 (medium): NOT-A-FINDING — SSRF in the Cloudflare CORS-proxy Worker; we neither ship nor deploy it.
|
||||
- GHSA-5xjf-rr5x-pcfj (medium): NOT-A-FINDING — same Worker.
|
||||
- GHSA-cx8x-7rrr-r9x8 (low): REAL (`<= v2.8.6`). An imported workflow file's TSA URL gets the SHA-256 of the user's PDF (client-side). No login; needs the user to import an attacker's workflow file and run it. Fixed in v2.8.7 (release note lists it; the advisory itself names no patched version).
|
||||
- release:v2.8.7: REAL security release (the three above).
|
||||
- release:v2.8.10: REAL security release — GHSA-v77x-cvmx-ggp4, GHSA-qch9-77q9-j7p6 "affecting all versions up to v2.8.9"; advisories still private (404 on 2026-10-27); severity/component unknown.
|
||||
Worst real: unknown (embargoed) / low known.
|
||||
|
||||
## Fix
|
||||
Smallest: v2.8.10 (covers cx8x + both embargoed). TARGET: v2.8.10 (ghcr tag v2.8.10 exists; also a plain 2.8.10). Same main: yes.
|
||||
Breaking (read v2.8.7..v2.8.10): none found. v2.8.8 big feature release (PDF text editor, Kura, Hyper Compress) — no config/env/port change stated; v2.8.9 timestamp CORS-proxy fallback only on official domains.
|
||||
Lane: SECURITY_FIX.
|
||||
## Classifier note
|
||||
Worker advisories (package "cors-proxy-worker.js") should not be flagged for the container image; cx8x shows "no fixed version" but v2.8.7's release note names it.
|
||||
@@ -0,0 +1,20 @@
|
||||
# bookstack — triage (group D)
|
||||
Pins: lscr.io/linuxserver/bookstack:26.09.1, mariadb:12.3 (no notices). Gates: none (own login only).
|
||||
|
||||
## Notice: release:BookStackApp/BookStack@v26.09.2 — REAL (app security release)
|
||||
Read body of v26.09.2 (2026-10-20). Fixes: (1) comments of pages in the recycle bin still visible to API users;
|
||||
(2) attachments of draft pages modifiable by other users holding attachment update/delete permission. Hardening: password
|
||||
change drops remember-me cookies, ZIP import uncompressed-size check, SAML2 route CSRF-logout nuisance, PHP packages.
|
||||
- Severity: unrated upstream (no GHSA); my read: low-medium (authorisation leaks between logged-in users).
|
||||
- Login: any user (API access / attachment permission). Reachable: yes, but only to an account holder.
|
||||
|
||||
## Fix / target
|
||||
Smallest fix: v26.09.2. Newest stable in main 26: v26.09.2 (newest release in the list).
|
||||
TARGET: `lscr.io/linuxserver/bookstack:26.09.2` — exists on Docker Hub (2026-10-26, same digest as v26.09.2-ls293).
|
||||
Tag style matches our pin (linuxserver bare version tag; it is re-pushed per ls build — ls291..ls293 so far).
|
||||
Same main: yes (26). Breaking: none found (read v26.09.1, v26.09.2; APP_KEY requirement came in v26.09, already behind us).
|
||||
linuxserver changelog: nothing since 05.08.26.
|
||||
Lane: SECURITY_FIX.
|
||||
|
||||
Classifier note: `behind` = `26.09.20260929` is wrong — linuxserver's date-suffixed tag for v26.09 sorts above 26.09.x;
|
||||
ignore `YY.MM.YYYYMMDD` tags when computing "behind".
|
||||
@@ -0,0 +1,11 @@
|
||||
# calcom — triage (group D)
|
||||
Pins: calcom/cal.com:v6.2.0 (source repo calcom/cal.diy), postgres:18-alpine.
|
||||
## GHSA-p3f6-52gv-cj7m (critical, 2024) — NOT-A-FINDING: about the project's own CI (`pull_request_target` workflow
|
||||
`.github/workflows/pr.yml` / check-types.yml repo takeover), not the shipped product.
|
||||
## GHSA-cpf2-q635-xrwx / CVE-2023-37919 (low, 2023) — NOT-A-FINDING: range "app.cal.com" (hosted service); NVD CPE
|
||||
range ends at <= 3.1.4, far below v6.2.0. Unsure whether v6.2.0 now ends other sessions on 2FA enable (NextAuth JWT
|
||||
sessions); even if not, it only matters to an attacker who already holds a stolen session.
|
||||
Lane: NOT_A_FINDING. No target.
|
||||
Side observation: Docker Hub calcom/cal.com newest tag is v6.2.0 (2026-03-02) and the release list ends there — no image
|
||||
in ~8 months; worth a staleness check (abandoned/renamed image?).
|
||||
Classifier note: drop advisories whose title names `.github/workflows`/`action.yml`, and ranges that are a hostname.
|
||||
@@ -0,0 +1,24 @@
|
||||
# code-server — triage (group D)
|
||||
Pin: lscr.io/linuxserver/code-server:4.129.0. Gates: none (code-server's own PASSWORD login is the only door).
|
||||
|
||||
## Notice: release:coder/code-server@v4.141.1 "Brotli decoder (CVE-2026-111497)" — REAL (bundled Node.js runtime + code-server change)
|
||||
- It is a Node.js bug (Node Oct 21 2026 security release: Brotli decoder OOB write -> RCE, high; affects 22.x/24.x/26.x).
|
||||
code-server ships its own Node in the release tarball; linuxserver's Dockerfile installs that tarball, so the image's
|
||||
Node is code-server's. `.node-version`: v4.129.0 = 24.18.0 (affected), v4.141.1 and v4.143.1 = 24.22.1 (fixed).
|
||||
- code-server itself also changed: "Reject compressed request bodies (br/gzip/deflate) instead of decompressing them"
|
||||
(commit range touches routes/index.ts + login.test.ts). code-server uses express ^5 (body-parser 2 inflates br),
|
||||
so a stranger's POST to /login with `Content-Encoding: br` reached the vulnerable decoder BEFORE authentication.
|
||||
- Severity: high (RCE). Login: none (pre-auth path via body parsing — strongly indicated by the fix, not tested live).
|
||||
Reachable: yes, public subdomain, no gate.
|
||||
|
||||
## Fix / target
|
||||
Smallest fix: 4.141.1 (linuxserver tag `4.141.1` exists, 2026-10-23). Newest stable: v4.143.1 (after 4.141.1 in
|
||||
CHANGELOG.md, same Node 24.22.1). TARGET: `lscr.io/linuxserver/code-server:4.143.1` (exists, 2026-10-24, = 4.143.1-ls373).
|
||||
Same main: yes (4). Read all 16 releases 4.130.0..4.143.1:
|
||||
- no data/file migration, no removed config, no new service. Behaviour changes: `--flag=false` in config now honoured
|
||||
(4.141.1); compressed request bodies refused (4.141.1); proxy cookies passed unchanged (4.132.0); `--unsafe-perm`
|
||||
removed from npm install scripts (4.134.0, not used by the image); 4.136.1 was withdrawn (data path bug) — skip it.
|
||||
- VS Code core 1.129 -> 1.143 (14 upstream releases): extension compatibility is the main practical risk; not a breaking
|
||||
change in the brief's sense. linuxserver: 20.09.26 IPv6 fallback only.
|
||||
Lane: SECURITY_FIX (large gap; recommend the box walk opens a terminal + an extension after the move).
|
||||
Classifier note: none (correct hit).
|
||||
@@ -0,0 +1,18 @@
|
||||
# dawarich — triage (group D)
|
||||
Pins: freikin/dawarich:1.15.3 (app + sidekiq), postgis/postgis:17-3.5-alpine, redis:7.4-alpine.
|
||||
|
||||
## release:Freika/dawarich@1.17.0 "Node.js 20 package, which no longer receives upstream security fixes" — NOT-A-FINDING
|
||||
It is maintenance: the image swaps Debian's EOL Node.js 20 for Node.js 22 LTS. Node there only runs the server-side
|
||||
poster renderer for a logged-in user's own data; no vulnerability is named or fixed. (Hygiene, not a finding.)
|
||||
|
||||
## Not flagged by the watch, but real hardening in 1.16.0 (affects 1.15.3)
|
||||
"Clear pending two-factor challenges after successful authentication, preventing a stale challenge from switching
|
||||
accounts"; "Prevent legacy or restored export URLs from deleting unrelated files"; admin-only test e-mail; protect last
|
||||
admin from deletion; secrets kept out of logs. All need a login. If the operator wants them: 1.16.0 (Docker Hub tag
|
||||
`1.16.0` exists, not the `-phoenix-rc*` tags) — changes: "/" redirects to sign-in (our healthcheck uses /api/v1/health,
|
||||
unaffected), background data backfills. 1.17.0+ is NOT quick-lane: the sidekiq container is removed (compose change:
|
||||
drop dawarich-sidekiq, SIDEKIQ_EMBEDDED, WEB_CONCURRENCY=0); 1.18.0 asks for a DB backup first, converts Areas into
|
||||
Places, breaking Visit API change.
|
||||
Lane: NOT_A_FINDING (optional SECURITY_FIX to 1.16.0 for the hardening; anything newer = BIG_STEP).
|
||||
Classifier note: the phrase "no longer receives upstream security fixes" describes a removed package — not a fix;
|
||||
and the watch missed 1.16.0's hardening because no line says "security".
|
||||
@@ -0,0 +1,19 @@
|
||||
# docmost — triage (group D)
|
||||
Pins: docmost/docmost:0.96.0, postgres:18-alpine, redis:7-alpine (no notices). Gates: setup_gate.
|
||||
|
||||
## Notice: release:docmost/docmost@v0.97.0 "security fixes for the latest Node" — REAL, runtime + dependencies
|
||||
- Image is FROM node:26-slim (since 0.96.0); Oct 21 2026 Node release fixes 26.x (Brotli high, TLS/DNS, ZipFile).
|
||||
- PR #2567 "update packages with security advisories": fastify 5.12.5, @fastify/multipart 10.1.2, socket.io 4.8.4,
|
||||
@nestjs/* 11.2.7, MCP sdk 1.32.1, dompurify 3.4.16, proxy-addr, engine.io, handlebars re-resolved. Upstream names no
|
||||
CVE ids; fastify/socket.io/multipart are pre-auth surfaces, specific exploitability unknown.
|
||||
- Docmost's own GHSAs (18 listed via the repo API): all patched at <= 0.95.0 — none affects 0.96.0.
|
||||
- Severity: unsure (no app advisory; Node CVE high). Login: unsure (pre-auth surfaces involved). Reachable: yes after
|
||||
the setup gate opens (public behind own login; public share pages exist).
|
||||
|
||||
## Fix / target
|
||||
Smallest fix = TARGET: `docmost/docmost:0.97.0` (Docker Hub, 2026-10-25; no `v`, matches pin). Same main: yes (0).
|
||||
Breaking: none found (read v0.97.0 full PR list). Note PR #2580: client IP now resolved through trusted proxies
|
||||
(replaces fastify-ip; CF-Connecting-IP only from Cloudflare edge hops) — our template strips X-Forwarded-For (R-753);
|
||||
re-check rate-limit IP on the box walk. PR #2596: API page content format defaults to json. New integrations are opt-in.
|
||||
Lane: SECURITY_FIX.
|
||||
Classifier note: none.
|
||||
@@ -0,0 +1,29 @@
|
||||
# gitea — triage (group C, 2026-10-27)
|
||||
Pin: gitea/gitea:1.27.3. Template: setup_gate + signup_block (/user/sign_up) + DISABLE_REGISTRATION after setup; sqlite; only port 3000 routed (no SSH port published, image's built-in SSH server off = default START_SSH_SERVER=false); Actions + Packages left at upstream default (ON); no runner shipped; migrations/mirrors at default (ALLOWED_DOMAINS unset, ALLOW_LOCALNETWORKS=false).
|
||||
|
||||
## Version line
|
||||
Gitea dropped the "1." prefix: 28.0.0 (2026-09-29) is the successor of 1.27.3 (secondary coverage: alternativeto.net, zeli.app; Go module renamed to gitea.dev, which is the package name in every new GHSA). No 1.27.4 exists (Docker Hub tag list read 2026-10-27: highest 1.27.x = 1.27.3). By the project rule the first number moves 1 -> 28 = new main version. Docker tags: 28.0.0 / 28.1.0 / 28.2.0 (no v).
|
||||
|
||||
## Notices (41)
|
||||
NOT-A-FINDING (1): GHSA-x4q3-gcj3-m6cf — package gitea.com/gitea/runner (act_runner); our template ships no runner.
|
||||
REAL (40) — all in range `<= 1.27.3` / `<= 28.0.0` / `<= 28.1.0`:
|
||||
- fixed 28.0.0: GHSA-467c, 4j4g, 54w9, 6g2h, 6pv5 (crit), 7769, 7cq7 (crit), 8pwg (crit), 93pj (crit), 9h7g, fqjr, g4hw, hcgw, mw6q, p3pc, p3rv, pvjf (crit), x8c3, xfqq, xh39
|
||||
- fixed 28.1.0: GHSA-469m, 7v5j, 8hhh, 94rx, 96qg, fx95, hf55, jj5r, vvqw, xmfc
|
||||
- fixed 28.2.0: GHSA-4jmf, 6f9g, 8j56, c3cr, cwq7, fxq4, mf69, vcp6, wx44
|
||||
- NO FIX: GHSA-rqhx-647v-wx32 (migration SSRF via HTTP redirect; fix 1.26.3 was REVERTED; gitea.dev >=1.27.1 open, no patched version).
|
||||
Reachability with OUR template (strangers cannot get an account: setup gate, then sign-up blocked twice):
|
||||
- Needs a household account (any user): 7cq7 container-registry stored XSS (Packages on), 6pv5, mw6q (instance crash), hcgw/p3pc/6g2h/g4hw/jj5r (mirror/migration SSRF/DoS), 94rx, 96qg, vvqw, cwq7, 8j56, fxq4, wx44, 4jmf (CSRF, victim must be signed in), xmfc, xfqq, x8c3, 7769, 469m, mf69, 467c.
|
||||
- Not reachable (feature off / absent): 8pwg + vcp6 (built-in SSH server off, no SSH port routed; vcp6 also needs SSH_TRUSTED_USER_CA_KEYS); Actions-runner chain pvjf/93pj/4j4g/xh39/6f9g (no runner => jobs never run; p3rv memory DoS still fires at run creation, needs an account); 54w9/fqjr (need ALLOWED_DOMAINS set); 7v5j (needs IMPORT_LOCAL_PATHS); 8hhh (needs DISABLE_NEW_PUSH); fx95 (needs FORCE_PRIVATE); 9h7g (needs INSTALL_LOCK reset).
|
||||
- Anonymous: c3cr (500/panic on /{user}/-/repositories, recovered per request), hf55 (activity feed of limited/private users via Accept header).
|
||||
Worst real: critical (7cq7, 6pv5 reachable by a household account).
|
||||
|
||||
## Fix
|
||||
Smallest fixing all fixable: 28.2.0. TARGET: gitea/gitea:28.2.0 (newest stable; same-main target does not exist). Same main: NO (1 -> 28).
|
||||
Breaking (read 28.0.0 [body truncated at 12000 chars], 28.1.0, 28.2.0): 28.0.0 BREAKING #39426 Git network ops routed through an internal proxy + new egress settings; #38855 RUN_RETENTION_DAYS deletes old Actions runs; per release coverage: self-registration off by default (we set it explicitly), a wildcard BLOCKED_DOMAINS can stop startup (we set none). 28.1.0/28.2.0: none found.
|
||||
Lane: BIG_STEP (40) + NO_FIX (rqhx). rqhx is likely closed by 28.0.0's egress proxy but the advisory names no fix — unsure.
|
||||
|
||||
## NO_FIX rqhx
|
||||
Blocks it: only a household account can start a migration; strangers have no account. Options: (A) set GITEA__repository__DISABLE_MIGRATIONS=true — cost: the household cannot import repos from GitHub etc.; (B) take 28.2.0 (BIG_STEP) and re-test the redirect against the new egress proxy — cost: a bench + box walk. If nothing: a household member could make Gitea fetch an internal address on the box network (a trusted-insider risk only).
|
||||
|
||||
## Classifier note
|
||||
x4q3 is package `gitea.com/gitea/runner`, not the server: match the advisory's package, not the repo. The 1.27 -> 28 rename should be stated in the item (it reads like a jump of 27 majors).
|
||||
@@ -0,0 +1,15 @@
|
||||
# glance — triage (pin glanceapp/glance:v0.8.5)
|
||||
|
||||
Template: `family_gate: true` (only signed-in household members reach it). Seeded glance.yml has NO `auth:` block (Glance has no login of its own here).
|
||||
|
||||
## Notices (1 GHSA)
|
||||
- GHSA-r225-jhr6-68cc (high, >= 0.8.0 <= 0.8.6, fixed 0.8.7): unbounded body read on POST /api/authenticate.
|
||||
NOT-A-FINDING: the route is registered only `if a.RequiresAuth` (internal/glance/glance.go @ v0.8.5 line 453-456); our seeded config
|
||||
enables no auth, so the endpoint does not exist. Even if a household adds auth, the family gate keeps strangers out.
|
||||
Real 0 / 1.
|
||||
|
||||
## Fix
|
||||
None required. Optional routine bump: `glanceapp/glance:v0.8.7` (Hub tag exists). Same main (0): yes. v0.8.7 note: Reddit widget `search`
|
||||
property needs `app-auth` now (our seed uses no reddit widget). v0.8.6: XFF rate-limit spoof fix (auth only).
|
||||
Lane: NOT_A_FINDING.
|
||||
Classifier note: GHSA-r225 applies only when Glance auth is configured; the watch cannot see the household's glance.yml, but for the catalog default it is not reachable.
|
||||
@@ -0,0 +1,33 @@
|
||||
# gokapi — triage (pin f0rc3/gokapi:v1.9.6)
|
||||
Template: NO gate field. First boot seeds config.json (internal auth, single user `admin`, Encryption Level 0 = E2E off). v1.9.x has NO multi-user
|
||||
system (added in v2.0.0) and NO File Requests (added v2.2.0).
|
||||
|
||||
## Notices (10)
|
||||
- 3c22-5j5m-4jq7 stored XSS via SVG hotlink — REAL (hotlinks exist in 1.9.6). high. Login: an uploader = only the admin. Reachable: self-XSS
|
||||
only on our template (no second account); low practical risk.
|
||||
- hcff-qv74-7hr4 login CSRF — REAL (code present). medium. Needs the attacker to know an account's password; only account is admin → not usable.
|
||||
- qwc6-vc2v-2ggj API unbounded body DoS — REAL (API present). medium. Login: admin/API key. Low.
|
||||
- NOT-A-FINDING (feature absent in 1.9.6 or single-user):
|
||||
- 45vh-rpc8-hxpp File Request MaxSize bypass — File Requests added in v2.2.0.
|
||||
- j6jp-78w8-34x6 file-replace permission escalation — v2 permission system.
|
||||
- m2hx-wjxc-9fp4 short-lived token escalation — v2 users/short-lived tokens (v2.2.0).
|
||||
- q658-hfpg-35qc API-key perms kept after rank demotion — user ranks are v2.
|
||||
- c36c-7pc2-f2ph uploadStatus leaks other users' file ids — single user only.
|
||||
- 4xg4-54hm-9j77 API-key friendly-name XSS — advisory: "If you are the only authenticated user ... not affected".
|
||||
- 95rc-wc32-gm53 filename XSS — needs E2E encryption (ours Level 0) + a second user.
|
||||
|
||||
## Fix
|
||||
Smallest fixing the 3 real: v2.2.4 (3c22/hcff → 2.2.3, qwc6 → 2.2.4). TARGET `f0rc3/gokapi:v2.2.4` (Docker Hub tag exists, `v` prefix as our pin).
|
||||
Same main: NO (1 → 2). No 1.x release after v1.9.6.
|
||||
Breaking (8 releases read, v2.0.0..v2.2.4): v2.0.0 user management, NO downgrade, "Requires v1.9.6 as base", config.json must be writable;
|
||||
our first-boot seed is pinned to ConfigVersion 21 (must be re-captured); v2.2.0 DOCKER_NONROOT deprecated, chunks >=5 MB, API FileList output
|
||||
changed, log deletion admin-only; v2.2.1 trusted proxies / GOKAPI_USE_CLOUDFLARE env (we strip XFF); v2.2.2 docker subnets auto-trusted;
|
||||
v2.2.3 SVG hotlinks removed on startup.
|
||||
Lane: BIG_STEP. Quick lane: NO_FIX (no 1.x fix).
|
||||
|
||||
## Options (no fix inside main 1)
|
||||
Blocks today: single-admin seed, E2E off — none of the 3 real items is usable by a stranger.
|
||||
- Option A: leave on 1.9.6 and record the residual (admin-only self-XSS/DoS) — cost: nothing; 1.9.6 is unmaintained (last 1.x Dec 2024).
|
||||
- Option B: BIG_STEP to v2.2.4 with a re-captured seed config — cost: bench migration + new seed + live share/download test.
|
||||
- If you do nothing: no stranger-reachable exposure from these notices; the app ages on an unmaintained branch.
|
||||
Classifier note: gokapi advisories after v2.0.0 describe multi-user / File Request features — range-only matching over-reports on 1.x.
|
||||
@@ -0,0 +1,19 @@
|
||||
# grafana — triage (group C, 2026-10-27)
|
||||
Pin: grafana/grafana:13.2.3. No gate field; Grafana login; admin password required from env; public sign-up off (upstream default allow_sign_up=false).
|
||||
|
||||
## Notices (4 + 1 release hit)
|
||||
All four GitHub advisories are 2022-era with unreadable/open ranges; every one was fixed years ago:
|
||||
- GHSA-2x6g-h2hg-rq84 CVE-2022-39306: NOT-A-FINDING — fixed 9.2.4 / 8.5.15 (its own text).
|
||||
- GHSA-4724-7jwc-3fpw CVE-2022-39324: NOT-A-FINDING — fixed in 9.2.8 / 9.3.2 / 8.5.16 (Grafana 2023-01 release; from memory, not re-read).
|
||||
- GHSA-8wjh-59cw-9xh4 CVE-2022-21673: NOT-A-FINDING — fixed 7.5.13 / 8.3.4 (2022-01; from memory). Range "> 7.2.0" has no upper end.
|
||||
- GHSA-8xmm-x63g-f6xv CVE-2022-23552: NOT-A-FINDING — fixed 9.2.10 / 9.3.4 / 8.5.16 (2023-01; from memory). Range ">=8.1" has no upper end.
|
||||
- release:v13.2.4 — REAL security release of Grafana: CVE-2026-15577 (Git Sync connection config modifiable with read-only access, 6.5), CVE-2026-33374 (unbounded memory in Prometheus rule conversion API, 6.5), CVE-2026-93294 (Azure Monitor resource proxy reaches arbitrary ARM APIs, 6.3), CVE-2026-95502 (Git Sync memory exhaustion via malicious Git server, 5.3); CVE-2026-92539 is Enterprise SCIM (we run OSS). Source: grafana.com/security/security-advisories listing, 2026-10-13. Affected ranges not on the listing.
|
||||
Login: all need a Grafana account (15577 read-only; others need editor/datasource rights — unsure exact role). Reachable: only accounts the household created. Git Sync and Azure Monitor are not configured by our template.
|
||||
Worst real: medium.
|
||||
|
||||
## Fix
|
||||
Smallest/TARGET: 13.2.4 (Docker Hub tag 13.2.4, no v; newest 13.2.x). Same main: yes.
|
||||
Breaking (read v13.2.4): none found — provisioning/Git Sync fixes, Alerting oauth2 header stripping.
|
||||
Lane: SECURITY_FIX (release hit); the 4 GHSAs NOT_A_FINDING.
|
||||
## Classifier note
|
||||
Drop advisories whose range is malformed/open-ended AND whose published date is >2 years older than the pinned release (all four here are 2022/2023, fixed in 8.x/9.x).
|
||||
@@ -0,0 +1,7 @@
|
||||
# home-assistant — triage (group D)
|
||||
Pin: ghcr.io/home-assistant/home-assistant:2026.9.4. Gates: setup_gate.
|
||||
## GHSA-jff5-5j3g-vhqc (low, 2023) — NOT-A-FINDING: GitHub Actions expression injection in the separate
|
||||
home-assistant/actions repo (`helpers/version/action.yml`, ecosystem "actions", fixed 2023-09-05); CI, not the product.
|
||||
Release bodies 2026.10.0..2026.10.4: no security mention.
|
||||
Lane: NOT_A_FINDING. No target.
|
||||
Classifier note: skip advisories with package ecosystem "actions".
|
||||
@@ -0,0 +1,33 @@
|
||||
# homebox — triage (pin ghcr.io/sysadminsmedia/homebox:0.26.2, single image, SQLite)
|
||||
|
||||
Template: `setup_gate: true`, `signup_block` on /api/v1/users/register, HBOX_OPTIONS_ALLOW_REGISTRATION off after setup.
|
||||
No notifier configured by default. One group per household normally.
|
||||
|
||||
## Notices (13 GHSA + 2 release hits) — all GHSA ranges include 0.26.2 (fixed 0.27.0; v0.27.0 body lists them)
|
||||
| id | sev | verdict | login | reachable |
|
||||
|---|---|---|---|---|
|
||||
| GHSA-jm28-2xm3-m6m5 | high | REAL: any group member can rename/delete/take over the group (cascade-deletes inventory) | any user | yes |
|
||||
| GHSA-58m4-m8xj-v3j2 | high | REAL: unauth register endpoint, no rate limit, Argon2id per request (DoS) | none | NO — register path refused by signup_block (setup_gate before) |
|
||||
| GHSA-xqg9-6xxv-3452 | medium | REAL: case-variant e-mail duplicate account -> victim login DoS (via register) | none | NO — signup_block |
|
||||
| GHSA-mw9p-fhpj-jf82 | medium | REAL: invitation quota race (via register) | invite token | NO — signup_block |
|
||||
| GHSA-754m-5j7m-8wfv | medium | REAL: X-Forwarded-Host into /swagger/doc.json | none | yes (impact needs a shared cache) |
|
||||
| GHSA-4p8r-vm9v-c9pm | low | REAL: login timing user enumeration | none | yes |
|
||||
| GHSA-rhfm-x4x2-p3qr | medium | REAL: generic:// notifier SSRF to localhost/RFC1918 (household LAN, box docker net) | any user | yes |
|
||||
| GHSA-4gp5-59x3-vhhg | medium | REAL: notifier SSRF via redirect | any user | yes |
|
||||
| GHSA-h7wm-wjr6-cfxh | medium | REAL: CSV formula injection in exports | any user | yes |
|
||||
| GHSA-59cq-p2m6-hh23 | medium | REAL: API keys survive password change, no expiry | stolen key | yes |
|
||||
| GHSA-g3p9-jfjj-pqgw | low | REAL: no revoke-other-sessions | stolen token | yes |
|
||||
| GHSA-j935-m3f2-frrj | medium | REAL: cross-group custom-field mutation | any user | only with 2+ groups (unusual on a box) |
|
||||
| GHSA-wxcf-4p4j-vhvg | medium | REAL: cross-group entity read via PUT | any user | only with 2+ groups |
|
||||
| release:v0.27.0 | - | REAL: the security release carrying the GHSAs above | - | - |
|
||||
| release:v0.27.1 | - | NOT-A-FINDING for the runtime: Node2Shell patch, but Dockerfile@v0.27.1 uses node:22-alpine only in build stages; final image is alpine + Go binary (no Node at runtime) | - | - |
|
||||
Real 14 / 15. Worst reachable: high (jm28, any user). Worst unauth (58m4) is blocked by our signup_block.
|
||||
|
||||
## Fix
|
||||
Smallest: 0.27.0. TARGET `ghcr.io/sysadminsmedia/homebox:0.27.1` (newest stable; ghcr manifest 0.27.1 and 0.27.0 exist — no `v` prefix, matching our pin). Same main (0): yes.
|
||||
Breaking/migrations 0.26.2 -> 0.27.1 (read v0.27.0-rc.1, v0.27.0, v0.27.1):
|
||||
- CAUTION 0.27.0: notifiers now BLOCK internal IPs by default — a household notifier pointed at a LAN/RFC1918 address stops working (that is the SSRF fix itself). Behaviour change, not data/config conversion.
|
||||
- "better search" (tokenized DB search, optional Meilisearch) — app-run DB change; Meilisearch optional.
|
||||
- No env rename, no file layout change, no new required service found.
|
||||
Lane: SECURITY_FIX (one caveat: internal-IP notifier block).
|
||||
Classifier note: release:v0.27.1 is a build-toolchain (Node) patch; Homebox ships no Node at runtime — should not count as an app/runtime fix.
|
||||
@@ -0,0 +1,12 @@
|
||||
# homepage — triage (group C, 2026-10-27)
|
||||
Pin: ghcr.io/gethomepage/homepage:v1.13.2. family_gate: true (only signed-in household members reach it). No app login. Starts with sample config; no credentialed service widgets configured by Felhom; Docker socket removed (R-981).
|
||||
|
||||
## Notices (1)
|
||||
- GHSA-669x-4pg4-w24r (medium, CVSS I:L, no auth): REAL (`< 2.2.0`). /api/services/proxy lets the caller pick method/body sent to a configured widget's upstream with the widget's stored credentials. Reachable only by a household member behind the family gate, and only if the household hand-wrote a credentialed widget.
|
||||
|
||||
## Fix
|
||||
Smallest: v2.2.0 (release note "Resolve GHSA-669x-4pg4-w24r"). No 1.x after v1.13.2. TARGET: v2.7.0 (ghcr tags v2.2.0, v2.7.0 exist). Same main: NO.
|
||||
Breaking (read v2.0.0..v2.7.0, 10 releases): v2.0.0 "Breaking: homepage auth" (#6769; the advisory PoC runs with HOMEPAGE_AUTH_ENABLED unset, so it looks opt-in — unsure, bench it with HOMEPAGE_ALLOWED_HOSTS); v2.6.0 auth architecture refactor + GHSA-qxcr-4rv3-v23r; v2.7.0 base image node 24, nextjs middleware -> proxy; v2.1.1 YAML parse bug (fixed 2.1.2).
|
||||
Lane: BIG_STEP (low urgency: family gate).
|
||||
## Classifier note
|
||||
none
|
||||
@@ -0,0 +1,21 @@
|
||||
# immich — triage (pins immich-server:v3.2.4, immich-machine-learning:v3.2.4)
|
||||
Template: setup_gate: true.
|
||||
|
||||
## Notices
|
||||
- GHSA-8244-8vpr-vp9c (CVE-2026-53662, critical, login-page `continue` XSS) — NOT-A-FINDING.
|
||||
Range is git-commit form (`> main@4ffa26c9`, patched `> main@4eb1003`); advisory text: "No tagged release is affected", bug only on `main`
|
||||
builds since 2026-04-15. Checked by hand via GitHub compare API: v3.2.4...4eb1003 = "behind" (fix commit 4eb100327e, "fix: disallow cross
|
||||
origin/non http protocols for continueUrl on login (#28706)", 2026-06-01) is an ANCESTOR of v3.2.4. Fix shipped before v3.0.0 (2026-07-02).
|
||||
- release:v3.3.5 — REAL runtime fix (no GHSA): Node.js Oct-2026 security release + certifi CA bundle / python image digests after the eMudhra
|
||||
CA compromise. Upstream: "we don't believe this ... brings an immediate danger". Severity: unsure (runtime; Node Brotli RCE CVE-2026-111497
|
||||
is in that Node release, exploit path in Immich not described). Login: n/a. Reachable: n/a (TLS trust + Node runtime).
|
||||
|
||||
## Fix
|
||||
No real GHSA. Optional runtime refresh: TARGET `ghcr.io/immich-app/immich-server:v3.3.5` AND `ghcr.io/immich-app/immich-machine-learning:v3.3.5`
|
||||
(both tags verified on ghcr; must move together).
|
||||
postgres (`ghcr.io/immich-app/postgres:16-vectorchord0.4.3-pgvectors0.2.0`) and `redis:7-alpine`: do NOT need to move — upstream
|
||||
docker/docker-compose.yml at v3.2.4 and v3.3.5 pins the identical postgres image (14-vectorchord0.4.3-pgvectors0.2.0, same digest) and valkey:9 in both.
|
||||
Same main (3): yes. Breaking: none found in 5 stable releases (v3.3.0, 3.3.1, 3.3.3, 3.3.4, 3.3.5) + 3 RCs; v3.3.0 ML model revision v2 is opt-in
|
||||
(`MACHINE_LEARNING_MODEL_REVISION=v2`), migrations self-run.
|
||||
Lane: NOT_A_FINDING for the GHSA; SECURITY_FIX (runtime) v3.3.5 if the operator wants the Node/CA refresh.
|
||||
Classifier note: GHSA ranges of form `main@<sha>` mean "untagged main builds" — treat as not affecting tagged pins unless the text says otherwise.
|
||||
@@ -0,0 +1,30 @@
|
||||
# jellyfin — triage (pin jellyfin/jellyfin:10.11.11)
|
||||
Template: setup_gate: true (closed to strangers until the startup wizard is done; probe StartupWizardCompleted).
|
||||
|
||||
## Notices (all 6 REAL by range — 10.11.11 is the last 10.x, released 2026-06-06; no 10.11.12 exists)
|
||||
| GHSA | sev | login | reachable on a box |
|
||||
|---|---|---|---|
|
||||
| 6828-c7cx-hvqm VirtualFolders path traversal → delete/move any dir | critical | none BEFORE wizard, admin after | before wizard: blocked by setup_gate; after: admin only (admin can already delete libraries) → low |
|
||||
| cf3c-8m59-2vhx SVG external refs → memory DoS + SSRF/local file read | high | any user (POST /UserImage) | yes, any household account |
|
||||
| hw73-62vp-9gxf HLS legacy segment path traversal, arbitrary file read | medium (AC:H, C:H) | NONE (legacy segment routes not [Authorize]) | YES — strangers, public subdomain |
|
||||
| 4vx8-xhc9-qg6x session remote-control broken access control (range <=12.0-RC5) | medium | any user | yes, household accounts |
|
||||
| 9x85-gx46-6522 playlist IDOR | medium | any user | yes, household accounts |
|
||||
| c39p-cgf8-866g plugin manifest ImagePath traversal | low | needs a malicious plugin (admin installs) | low |
|
||||
|
||||
## Fix
|
||||
Smallest fix: 12.0 (all six). TARGET `jellyfin/jellyfin:12.4` (Docker Hub tag exists; build tag 12.4.20261026-211555; jellyfin 12 uses
|
||||
two-part versions). Same main: NO (10 → 12).
|
||||
Breaking (read v12.0 notes; 12.1–12.4 not needed for the verdict): DB changes with no rollback without full restore; repository plugins must be
|
||||
removed before migrating; a FULL LIBRARY SCAN is required after upgrade (auto-resolved alternate versions removed); legacy /emby and
|
||||
/mediabrowser routes removed; legacy authorization disabled by migration; global subtitle config removed; usernames differing only by case must
|
||||
be fixed before upgrade; obsolete API routes removed.
|
||||
Lane: BIG_STEP (12.4). Inside main 10: no fixed release (NO_FIX in the quick lane).
|
||||
|
||||
## Until the big step (what blocks it today / options)
|
||||
Blocks today: setup_gate covers the critical's anonymous window. Nothing blocks hw73 (stranger file read) or the any-user ones.
|
||||
- Option A: traefik rule refusing the legacy HLS segment paths (GetHlsAudioSegmentLegacy / GetHlsVideoSegmentLegacy / GetHlsPlaylistLegacy — exact
|
||||
route strings to be read from HlsSegmentController.cs at v10.11.11 before writing the rule; not guessed here) — cost: one template label + a live playback test (modern clients use the non-legacy HLS routes; unsure which clients still use legacy).
|
||||
- Option B: schedule the 12.4 big step now — cost: tested migration on the bench, full library rescan on every box, plugin removal.
|
||||
- If you do nothing: a stranger who can reach the subdomain may read files the jellyfin process can read (AC:H), and any household account can
|
||||
exhaust memory / SSRF via an SVG avatar.
|
||||
Classifier note: none.
|
||||
@@ -0,0 +1,25 @@
|
||||
# karakeep — triage (pins ghcr.io/karakeep-app/karakeep:0.33.2, ghcr.io/karakeep-app/karakeep-chrome:151.0.7922.47-r1; meilisearch v1.41.0 untouched)
|
||||
Template: setup_gate: true + signup_block (signup + tRPC users.create). Browser: our compose uses `karakeep-chrome:151.0.7922.47-r1`
|
||||
(BROWSER_WEB_URL=http://karakeep-chrome:9222, internal network only) — EXACTLY the vulnerable image.
|
||||
|
||||
## Notices
|
||||
- GHSA-pp34-2c9r-mchw — REAL. high (two CISA-KEV V8 bugs CVE-2026-85046 / CVE-2026-87491, Chromium started with --no-sandbox).
|
||||
Login: any user (anyone who can save a bookmark/RSS feed makes the crawler open the page; a hostile page needs no account of its own).
|
||||
Reachable: yes — through content the household saves; strangers cannot submit URLs (gate + signup_block).
|
||||
The GHSA lists no patched version, BUT the registry now has `karakeep-chrome:154.0.8037.57-r1` and `156.0.8078.47-r1` (>= 153.0.8010.36 = both fixed).
|
||||
v0.34.x source (docker/chrome/Dockerfile) pins GOOGLE_CHROME_VERSION=154.0.8037.57 on debian trixie-slim (Google Chrome on amd64;
|
||||
arm64 falls back to Debian's chromium — version not pinned, unsure if >=153 on arm64).
|
||||
- release:v0.34.1 — REAL runtime fix: node:24-slim (24.22.1), Oct-2026 Node security release (Brotli OOB write, TLS hostname bypasses).
|
||||
- release:v0.34.0 — REAL: Next.js 16.4.1 October security release (#3196) + GHSA-892w-x93w-2fqp (list cycle → infinite loop, any user; not in the watch's list).
|
||||
|
||||
## Fix
|
||||
Smallest: chrome image 154.0.8037.57-r1. TARGET: `ghcr.io/karakeep-app/karakeep:0.34.1` + `ghcr.io/karakeep-app/karakeep-chrome:154.0.8037.57-r1`
|
||||
(the pair v0.34.1 ships; 156.0.8078.47-r1 also exists, unsure which karakeep release it is tested with). Tags verified on ghcr (no `v` prefix).
|
||||
Same main (0): yes.
|
||||
Breaking (0.34.0, 0.34.1 read): auth library next-auth → better-auth (automatic DB migration), EVERY web user signed out once; emails lowercased
|
||||
in DB — two accounts differing only by case lock the user out (manual fix before upgrade); new optional AUTH_TRUSTED_ORIGINS; chrome image is now
|
||||
full Google Chrome (bigger; 768M limit and the bash healthcheck must be re-measured); crawler driven by patchright.
|
||||
Lane: BIG_STEP (forced sign-out + auth data conversion + rebuilt browser image). A chrome-only bump (151 → 154) with app 0.33.2 is
|
||||
unsure: not tested upstream as a pair (the GHSA reporter's own replacement image did work with 0.33.2).
|
||||
Classifier note: "no fixed version named yet" is stale — the karakeep-chrome registry has 154/156 tags past the KEV fixes; the watch should read
|
||||
the chrome image's registry tags against the advisory's fixed Chromium version.
|
||||
@@ -0,0 +1,15 @@
|
||||
# mealie — triage (pin ghcr.io/mealie-recipes/mealie:v3.28.0, single image, SQLite)
|
||||
|
||||
Template: no gate field; ALLOW_SIGNUP=false; Mealie's own login is the door. No OIDC/LDAP/OpenAI env.
|
||||
|
||||
## Notices (1 GHSA)
|
||||
- GHSA-99wf-32rc-2767 (medium, <= 3.28.0, patched 3.29.0): REAL — recipe zip import trusts object ids across GROUPS
|
||||
(take over another group's tools, read another group's recipe). Login: any user. Reachable: only on a box with 2+ groups
|
||||
(default is one group "home"); with one group there is no other group to attack.
|
||||
Real 1 / 1.
|
||||
|
||||
## Fix
|
||||
Smallest 3.29.0; TARGET `ghcr.io/mealie-recipes/mealie:v3.29.0` (newest stable; ghcr tags v3.28.0, v3.29.0 — `v` prefix as our pin). Same main (3): yes.
|
||||
Breaking/migrations (read v3.29.0 full body via GitHub API, 16.9k chars): none found. App-run DB changes (structured recipe times, trigram indexes on Postgres — we use SQLite). New reverse-proxy auth is OFF by default (settings.py@v3.29.0 REVERSE_PROXY_AUTH_ENABLED=False). Docs drop obsolete OIDC_SIGNING_ALGORITHM (we do not set it). New iCal feed is opt-in.
|
||||
Lane: SECURITY_FIX.
|
||||
Classifier note: none.
|
||||
@@ -0,0 +1,22 @@
|
||||
# n8n — triage (pin n8nio/n8n:2.42.1, single image, SQLite)
|
||||
|
||||
Template: `setup_gate: true` (owner setup); public behind n8n's own login after that; webhook URLs public by design.
|
||||
NODES_EXCLUDE NOT set in our compose -> n8n 2.x default applies: packages/@n8n/config nodes.config.ts @ n8n@2.42.1
|
||||
`exclude = ['n8n-nodes-base.executeCommand', 'n8n-nodes-base.localFileTrigger']`.
|
||||
|
||||
## Notices (13 GHSA, no release hits)
|
||||
- GHSA-365g-vjw2-grx8 (high, "> 0.0.1", no fix): NOT-A-FINDING on our template — Execute Command node is excluded by default
|
||||
in 2.x and our compose keeps the default; the advisory's own mitigation is exactly that NODES_EXCLUDE. (Becomes real only
|
||||
if someone sets NODES_EXCLUDE=[] .) Optional hardening: pin `NODES_EXCLUDE` explicitly in the compose so a future default change cannot reopen it.
|
||||
- REAL (12), all need a logged-in member who can create/run workflows (or view executions); multi-user boxes only matter for the credential-isolation ones:
|
||||
- high: GHSA-m7gv-mpg5-7c9v (glob ReDoS blocks n8n), GHSA-mp7q-23hg-35cf (stored XSS via webhook response — victim opens a public webhook URL), GHSA-wvjj-qg37-pv73 (Data Tables of other projects)
|
||||
- medium: GHSA-43v8 (Chat Hub chat-user tools), -mgpr (Outlook/SharePoint OData injection, workflow-dependent), -8vrr, -v9cx, -8crx (credential checks bypass), -qmvv, -crfj (secrets in execution error data), -pcr3 (error-workflow identity; fixed 2.42.2), -65mv (Quick Base filter injection, workflow-dependent).
|
||||
Real 12 / 13. Worst: high, login = any workflow-capable member, reachable yes (behind n8n login).
|
||||
|
||||
## Fix
|
||||
Smallest fixing all real: 2.43.5 (pcr3 >= 2.42.2; rest >= 2.43.5 / 2.44.1; 2.42.x line has no fix for the rest).
|
||||
TARGET `n8nio/n8n:2.44.7` — newest STABLE 2.x: GitHub `stable` tag = n8n@2.44.7 (2026-10-26); `beta` = n8n@2.45.4, so 2.45.x is excluded. Hub tag 2.44.7 exists. Same main (2): yes.
|
||||
Breaking/migrations 2.42.1 -> 2.44.7 (read 23 release bodies n8n@2.42.2..2.44.7; 2.43.0 and 2.44.0 truncated at 12000 chars, so also read packages/cli/BREAKING-CHANGES.md @ n8n@2.44.7: no entry between 2.0.0 and 2.44.7):
|
||||
- none found. Note: 2.42.6/2.43.3 "Block create/update of workflows with deprecated nodes" — existing workflows run; editing one that uses a deprecated node is refused (behaviour change, not data).
|
||||
Lane: SECURITY_FIX. (GHSA-365g is NOT_A_FINDING, not NO_FIX.)
|
||||
Classifier note: GHSA-365g ("> 0.0.1", no fix) should be suppressed for n8n >= 2.0 when the compose does not override NODES_EXCLUDE — the node is off by default.
|
||||
@@ -0,0 +1,29 @@
|
||||
# outline — triage (pin outlinewiki/outline:1.10.1; sidecars postgres:18-alpine, redis:7-alpine not in scope)
|
||||
|
||||
Template auth: NO SSO configured (no AZURE_*/DISCORD_*/OIDC_*/GOOGLE_*/SLACK_*/GITLAB_* env). Sign-in = e-mail magic link
|
||||
(`login_kind: email`) + passkeys. Gates: `setup_gate: true` only (public behind Outline's own login after setup). One workspace per box.
|
||||
|
||||
## Notices (12 GHSA + 1 release hit)
|
||||
| id | sev | verdict | login | reachable |
|
||||
|---|---|---|---|---|
|
||||
| GHSA-f28f-75h4-499q | critical | NOT-A-FINDING: Azure SSO callback only; template configures no Azure provider | - | no |
|
||||
| GHSA-m9vh-j2wc-xj24 | high | NOT-A-FINDING: Azure/Discord OAuth adapters only; neither configured | - | no |
|
||||
| GHSA-48rq-wx9j-g949 | critical | NOT-A-FINDING: needs 2+ OAuth/OIDC providers on one team; template has none (email+passkey do not use providerId rows) | - | no |
|
||||
| GHSA-27h6-gg7j-wj5w | medium | NOT-A-FINDING: GitLab integration plugin; not configured, and cross-tenant needs a 2nd workspace | - | no |
|
||||
| GHSA-x4w3-9p9j-cprh | low | NOT-A-FINDING: cross-TEAM user-id oracle; a box runs one workspace | - | no |
|
||||
| GHSA-97vv-f6qq-6842 | high | REAL (<1.11.0): write API key/OAuth token can register passkey / change e-mail -> takeover | needs a victim's leaked write token | yes |
|
||||
| GHSA-w8vg-8mjx-xq8x | high | REAL (<1.11.0): logged-out JWT keeps collab websocket | any user (stolen session) | yes |
|
||||
| GHSA-65xg-84g9-7hrm | medium | REAL (<1.11.0): collab socket writable after archive/delete | any user | yes |
|
||||
| GHSA-rq53-m97j-f2pg | high | REAL (<1.12.0): unpublished doc's public share keeps working, cannot be revoked | none (holder of an old share link) | yes — public share links are used (our guide teaches "Publish to web") |
|
||||
| GHSA-h6ff-rw9x-5mq2 | medium | REAL (<1.12.0): member publishes into private collection | any user | yes |
|
||||
| GHSA-rvj7-2gww-6xfq | low | REAL (<1.12.0): shares.info leaks private collection name/path | none (share link holder) | yes |
|
||||
| GHSA-cprf-crfh-w3p4 | low | REAL (<1.12.0): e-mail sign-in token replayable within 10 min from same IP | none (needs the link + same IP) | yes — e-mail sign-in is OUR login method |
|
||||
| release:v1.12.0 | - | REAL: image Node.js upgraded to 26.12.1 (Node security release); Outline runs on Node at runtime | - | - |
|
||||
|
||||
Real 8 / 13. Worst real: high (97vv, w8vg, rq53). rq53 needs no login.
|
||||
|
||||
## Fix
|
||||
Smallest fixing all real: 1.12.0. TARGET: `outlinewiki/outline:1.12.0` (newest stable; Docker Hub tags 1.12.0 / 1.12 / latest seen; no 1.12.x patch yet). Same main (1): yes.
|
||||
Breaking/migrations 1.10.1 -> 1.12.0 (read v1.11.0, v1.12.0; v1.12.0 full body via API): none found. Notes: v1.12.0 "Migrations before v1.3.0 compacted into a baseline schema" (irrelevant from 1.10.1); app-run DB migrations; new personal-documents feature; "authentication requirements on account settings routes tightened" (1.11.0). No env renames, no new required service.
|
||||
Lane: SECURITY_FIX.
|
||||
Classifier note: the 5 SSO/GitLab/cross-team notices are config-dependent; classifier cannot know — fine to list, but it should not count Azure/Discord/OIDC/GitLab notices as "critical for the box" without a template-env check.
|
||||
@@ -0,0 +1,13 @@
|
||||
# paperless-ngx — triage (group C, 2026-10-27)
|
||||
Pin: ghcr.io/paperless-ngx/paperless-ngx:2.20.15 (+ postgres:18-alpine, redis:7-alpine — not in scope). No gate field; app login is the only door; no public sign-up (allauth signup off by default); admin from env. AI features do not exist in 2.x.
|
||||
|
||||
## Notices (2)
|
||||
- GHSA-c8f3-pqr2-rr24 (medium, AI classification on ownerless docs): NOT-A-FINDING — range "3.0–3.3.2"; AI features arrived in 3.0.0, our 2.20.15 is below.
|
||||
- GHSA-2jhj-xqrq-rmrq (low, path traversal when FILENAME_FORMAT_REMOVE_NONE): REAL by range (`<= 3.1.1`), fixed 3.1.2 (release note names it). Needs a user who can edit a storage-path/filename template AND the env PAPERLESS_FILENAME_FORMAT_REMOVE_NONE=true — our compose does not set it => NOT reachable on a box.
|
||||
|
||||
## Fix
|
||||
Smallest: 3.1.2. No 2.20.x after 2.20.15 (release list read; ghcr has 2.20.15, 3.1.2, 3.3.4). TARGET (only path): 3.3.4 (tag style no v). Same main: NO.
|
||||
Breaking (3.0.0 notes): consume-script positional args removed; OCR/archive control decoupled; API < v9 and API v1 dropped; Python 3.10 dropped; advanced DB settings refactored; pyzbar removed; document/thumbnail ENCRYPTION removed; consumer reworked; Whoosh -> tantivy search index (index rebuild). 3.3.4 itself = dependency security (certifi, Pillow, aiohttp).
|
||||
Lane: BIG_STEP, not urgent (the one real notice is low and not reachable).
|
||||
## Classifier note
|
||||
c8f3's package name is misspelt "papaerless-ngx" and the range is "3.0–3.3.2" (en dash) — the classifier should have parsed it as >=3.0 and dropped it for 2.20.15.
|
||||
@@ -0,0 +1,17 @@
|
||||
# privatebin — triage (pin privatebin/pdo:2.0.6)
|
||||
|
||||
Template: no gate field; PrivateBin has no login — anyone with the URL can create and read pastes (by design). No custom cfg/conf.php mounted (only /srv/data).
|
||||
|
||||
## Notices (1 GHSA + 1 release hit)
|
||||
- GHSA-w873-3ghv-hmh6 (medium, <= 2.0.6, patched 2.1.0): REAL — Markdown HTML keeps `class` attributes, so a paste can draw a fake
|
||||
Bootstrap modal (phishing). Login: none. Reachable: yes (public subdomain, anyone can create a Markdown paste and send the link).
|
||||
- release:2.1.0: REAL — the release carrying that fix plus MIME-sniff header fix and comment-file handling fixes.
|
||||
Real 2 / 2.
|
||||
|
||||
## Fix
|
||||
Smallest 2.1.0; TARGET `privatebin/pdo:2.1.0` (newest stable; Hub tags 2.1.0 / stable / latest). Same main (2): yes.
|
||||
Breaking (read 2.1.0; 2.0.6 baseline): "This release removes the bootstrap (3) template" + jQuery removed. Action only if a custom conf.php sets
|
||||
`template = bootstrap` or lists bootstrap templates — our template mounts no conf.php (image default config). A viewer's
|
||||
saved template cookie is irrelevant unless template switching is enabled (default off). No data conversion.
|
||||
Lane: SECURITY_FIX.
|
||||
Classifier note: none.
|
||||
@@ -0,0 +1,24 @@
|
||||
# rallly — triage (pin lukevella/rallly:4.15.3; postgres:18-alpine untouched)
|
||||
Template: setup_gate: true (closed to strangers only until first admin; public after). No SSO / conferencing env in compose.
|
||||
|
||||
## Notices
|
||||
- GHSA-gmq4-f8j5-8w8q — REAL. critical (CVSS 9.8-class, Next.js next/og RCE). Range >=4.8.0 <4.15.4 covers 4.15.3.
|
||||
Login: none (`/api/og-image-poll` unauthenticated). Reachable on a box: YES once setup is done (public subdomain).
|
||||
Fixed 4.15.4.
|
||||
- release:v4.15.4 — REAL, same as the GHSA above.
|
||||
- release:v4.15.5 — REAL: Next.js GHSA-p3m5-59mp-jv5r Server Actions DoS (high, no login). Fixed 4.15.5.
|
||||
- release:v4.16.2 — REAL runtime fix: image rebuilt on Node.js 24.22.1 (Oct-2026 Node security release, Brotli RCE CVE-2026-111497 + TLS/DNS).
|
||||
- release:v4.16.0 — NOT-A-FINDING: hit on "Control Panel tells you ... whether it fixes a security issue" (feature text).
|
||||
|
||||
## Fix
|
||||
Smallest fix for the GHSA: 4.15.4. Smallest fixing every real item: 4.16.2. TARGET: `lukevella/rallly:4.16.3` (Docker Hub tag exists; no `v` prefix, as our pin).
|
||||
Same main (4): yes.
|
||||
Breaking/migrations read in 6 releases (4.15.4..4.16.3):
|
||||
- 4.16.0: 13 DB migrations run on start (additive — fine); Microsoft multi-tenant SSO sign-in now needs verified email claims (we ship no MS SSO);
|
||||
`SMTP_DEBUG` no longer does anything (not in our compose); new in-memory rate limit 200 responses/poll/hour, needs X-Real-IP from the proxy
|
||||
(our compose strips XFF, traefik sets X-Real-Ip — verify live that the tunnel does not make every visitor one IP); new hourly update check to api.rallly.co.
|
||||
- 4.16.1: optional GOOGLE_/MICROSOFT_LOGIN_ENABLED. 4.16.3: DST fix only.
|
||||
None of these is a file migration, a removed config we use, or a new required service.
|
||||
Lane: SECURITY_FIX to 4.16.3. (Conservative alternative: 4.15.5 = Next.js fixes only, but it misses the Node runtime fix of 4.16.2.)
|
||||
Workaround until shipped: block `/api/og-image-poll` at traefik.
|
||||
Classifier note: release:v4.16.0 is a word-match on "security issue" in a feature description — not a fix.
|
||||
@@ -0,0 +1,24 @@
|
||||
# romm — triage (pin rommapp/romm:5.3.1; sidecars mariadb:11.8, redis:7-alpine not in scope)
|
||||
|
||||
Template: `setup_gate: true` only; KIOSK_MODE not set (off); X-Forwarded-For stripped by traefik middleware romm-xff.
|
||||
|
||||
## Notices (4 GHSA + 2 release hits)
|
||||
| id | sev | verdict | login | reachable |
|
||||
|---|---|---|---|---|
|
||||
| GHSA-722m-w9p2-xv2j | high | REAL (<5.4.0): Socket.IO `scan`/`scan:stop` unauthenticated; a `complete` scan deletes all on-disk media and rewrites ROM rows | none | YES — /ws/socket.io on the public subdomain, no upstream auth after setup |
|
||||
| GHSA-q7fg-rj3q-m3gm | medium | REAL: read others' private collections/favourites via /api/roms filters (anonymous only with KIOSK_MODE, off here) | any user | yes |
|
||||
| GHSA-7jw3-ppmp-57wc | medium | REAL: hidden-ROM child routes skip visibility check | any user | yes (only matters if admin hides ROMs) |
|
||||
| GHSA-9q83-m866-5jrp | medium | REAL: public save download bypasses hidden-ROM check | any user | yes (same) |
|
||||
| release:5.4.0 | - | REAL: release carries the 4 fixes + renovate "[security]" dependency bumps | - | - |
|
||||
| release:5.4.1 | - | REAL (runtime deps): pillow v13 [security], certifi (eMudhra CA distrust), aiohttp bump, pip upgrade; Node 24.22.1 bump (likely build-stage only, unsure) | - | - |
|
||||
Real 6 / 6. Worst: high, no login, reachable.
|
||||
|
||||
## Fix
|
||||
Smallest: 5.4.0. TARGET `rommapp/romm:5.4.1` (newest stable; Hub tags 5.4.1 / 5.4 / 5; we use the non-slim tag). Same main (5): yes.
|
||||
Breaking/migrations 5.3.1 -> 5.4.1 (read 5.4.0-alpha.1, -alpha.2, -beta.1, 5.4.0, 5.4.1):
|
||||
- CAUTION 5.4.0: first start runs migrations that REWRITE the roms table in batches, "give 15-20 min, don't restart the container while they run". App-run DB migration (allowed by the rule) BUT a restart/rollback mid-migration is the risk — the update path must not time out and roll back during it.
|
||||
- ROMM_CORS_ALLOWED_ORIGINS default now deny (same-origin UI unaffected); FORWARDED_ALLOW_IPS default now loopback/private only (traefik is on a private docker net; we strip XFF anyway).
|
||||
- API ⚠ changes (removed schema fields, netplay rooms need login, scan payload validated strictly) — affect external API clients only.
|
||||
- No env rename, no file layout change, no new required service (SMTP etc. optional).
|
||||
Lane: SECURITY_FIX (with the long-migration caution — operator may prefer to watch the first box).
|
||||
Classifier note: none.
|
||||
@@ -0,0 +1,31 @@
|
||||
# seerr — triage (pin fallenbagel/jellyseerr:2.7.3)
|
||||
Upstream renamed: Jellyseerr/Overseerr → Seerr (seerr-team/seerr). 2.7.3 is the last 2.x (Docker Hub now also has `2.7.3-deprecated`).
|
||||
Template: setup_gate: true; no signup_block (Seerr accounts come from the media server's users). Volume /app/config.
|
||||
|
||||
## Notices (all 6 REAL by range; /avatarproxy route confirmed present in v2.7.3 source: server/routes/avatarproxy.ts, mounted in server/index.ts)
|
||||
| GHSA | sev | login | reachable on a box |
|
||||
|---|---|---|---|
|
||||
| rc4w-7m3r-c2f7 unauthenticated account registration via /auth/jellyfin | high | none | ONLY if the household configured Plex (Jellyfin-configured installs not affected) |
|
||||
| mc6w-69r3-62h8 /avatarproxy ETag path traversal → file write → RCE (AV:A) | high | none to trigger; attacker must control the media server's HTTP response or MITM the plaintext seerr→media-server link | low (media server is the household's own, usually same box/LAN) |
|
||||
| f7xw-jcqr-57hp GET /user/:id leaks others' notification creds | medium | any user | household accounts |
|
||||
| gx3h-3jg5-q65f pushSubscription routes missing owner check (>=2.7.0) | medium | any user | household accounts |
|
||||
| 8j73-j6rc-q8xh request detail endpoints leak others' notification creds | medium | any user | household accounts |
|
||||
| xc6j-6p6h-p799 /movie/:id, /tv/:id leak email/plexId | medium | any user | household accounts |
|
||||
|
||||
## Fix
|
||||
Smallest fixing all: 3.5.0. TARGET image (3.x has a NEW name): `ghcr.io/seerr-team/seerr:v3.5.1` (ghcr tag list verified: v3.0.0..v3.5.1; also
|
||||
Docker Hub `seerr/seerr:v3.5.1`). Note the `v` prefix in 3.x (our 2.x pin has none). v3.5.1 adds Node 22.23.4 (eMudhra CA distrust).
|
||||
Same main: NO (2 → 3).
|
||||
Breaking (10 releases read v3.0.0..v3.5.1): image renamed; container now runs as `node` UID 1000 → /app/config volume must be chowned 1000:1000
|
||||
(manual step); automatic Jellyseerr→Seerr settings/DB migration on first start; 3.3.0 webhook field discordID → discordIDs (breaking);
|
||||
3.5.0 library API endpoints changed (UI unaffected).
|
||||
Lane: BIG_STEP. No fix inside main 2 (quick lane: NO_FIX).
|
||||
|
||||
## Options (no fix inside main 2)
|
||||
Blocks today: setup_gate until first admin; rc4w only on Plex-configured boxes; others need a household account.
|
||||
- Option A: traefik refuses `POST /api/v1/auth/jellyfin` on Plex-configured boxes — cost: per-box config knowledge the template does not have; breaks
|
||||
Jellyfin login if the household later switches. Weak.
|
||||
- Option B: BIG_STEP to ghcr.io/seerr-team/seerr:v3.5.1 with a chown step — cost: bench migration test, a volume-ownership step in the update path.
|
||||
- If you do nothing: on a Plex-configured box a stranger can create an account and file requests (then read other users' notification tokens).
|
||||
Classifier note: watch item names upstream `fallenbagel/jellyseerr`; future fixes only appear under `ghcr.io/seerr-team/seerr` — point the pin's
|
||||
registry source there or the watch will never see a newer tag.
|
||||
@@ -0,0 +1,19 @@
|
||||
# sparkyfitness — triage (group C, 2026-10-27)
|
||||
Pins: codewithcj/sparkyfitness_server:v0.17.3, codewithcj/sparkyfitness:v0.17.3 (+ postgres:18-alpine). setup_gate + signup_block (/api/auth/sign-up) + SPARKY_FITNESS_DISABLE_SIGNUP after setup. BETTER_AUTH_SECRET: generated per install (`generate: "hex:32"`, data_key, locked). Register: R-785 (P3, walk 0.17 -> 1.x after R-784); R-784 licence (decision 65: keep offered, ask author).
|
||||
|
||||
## Notices (3, same on both images)
|
||||
- GHSA-v883-jx9h-qf29 (medium): NOT-A-FINDING — only an install that kept the .env.example placeholder secret is exposed; our template generates a random BETTER_AUTH_SECRET per install. (Upstream fix: v1.7.3 "refuse to start with .env template placeholder secrets" #2617.)
|
||||
- GHSA-cmmf-53wf-r5gv (low): REAL (`>= 0.17.3, <= 1.6.5`, patched "None" — advisory page re-read 2026-10-27). Pregnancy photos served from the public /uploads static mount; no login needed but the attacker must already hold the full URL (user/pregnancy UUIDs + timestamp).
|
||||
- GHSA-p8cf-g8rv-gvrq (medium): REAL (`>= 0.15.8.1, <= 1.6.5`, patched "None"). Needs an account + victim's UUID + victim's configured Withings client => household accounts only.
|
||||
Worst real: medium.
|
||||
|
||||
## Fix
|
||||
No fixed version named. Releases after v0.17.3 exist (v1.6.0..v1.9.0, Docker Hub tags v1.9.0 on both images), but none of their notes (v1.6.0..v1.9.0 read, grep for withings/upload/pregnancy/GHSA/security) names either fix; the advisory ranges stop at 1.6.5 only because that was the version tested. Unsure whether 1.9.0 fixes them.
|
||||
If moved anyway (R-785): TARGET v1.9.0 for both images; same main NO (0 -> 1). Breaking: v1.6.0 unified versioning, MCP decommissioned; v1.6.1 Postgres upgrade mandated (we already run 18); v1.7.0 BREAKING ALLOW_PRIVATE_NETWORK_FOOD_PROVIDERS for private Tandoor/Mealie; v1.7.2 BREAKING env vars removed (moved to admin settings), mandatory list reduced; v1.9.0 adaptive-calorie behaviour change.
|
||||
Lane: NO_FIX (cmmf, p8cf). BIG_STEP stays R-785.
|
||||
|
||||
## NO_FIX options
|
||||
cmmf — blocks it: URL unguessable; pregnancy tracking is a mobile-app feature. (A) do nothing, record: cost 0; if nothing, a leaked photo URL opens that one photo without login. (B) traefik rule refusing /uploads/pregnancy and /api/uploads/pregnancy: cost a template change + walk, and it also breaks photo display for the owner.
|
||||
p8cf — blocks it: setup gate + sign-up closed => only household members; needs a configured Withings integration. (A) do nothing, watch upstream: if nothing, a household member could overwrite another member's Withings link (data integrity, trusted insiders). (B) walk to v1.9.0 under R-785 and test the Withings callback: cost = the BIG_STEP walk; unsure it is fixed.
|
||||
## Classifier note
|
||||
v883: when an advisory is about a default/placeholder secret, check the template's `generate:` for that env var — sparky generates BETTER_AUTH_SECRET.
|
||||
@@ -0,0 +1,15 @@
|
||||
# tandoor — triage (group C, 2026-10-27)
|
||||
Pin: ghcr.io/tandoorrecipes/recipes:2.6.15 (+ postgres:17-alpine). setup_gate; no signup_block (ENABLE_SIGNUP not set = upstream default off); household added by invite link. Health probe and compose healthcheck use /accounts/login/.
|
||||
|
||||
## Notices (9 + 1 release hit)
|
||||
NOT-A-FINDING (1): GHSA-cqj3-64qw-4w52 — fixed in 2.6.10 (release note links it), below our pin; range field unreadable.
|
||||
REAL (8), all named as fixed in the 2.7.0 release notes: GHSA-5f74 (high, XXE local file read in rezeptsuite/Cookmate importers + pestle SSRF), GHSA-69q3 (high, group-permission cache across spaces), GHSA-5p9v, pcq2, xq7g, 748x, c7mc, vc5c (medium). release:2.7.0 = the same real fixes (+ "lots of dependencies, several security issues").
|
||||
Login: any user (import permission / same space). Reachable: household accounts only (setup gate, no public sign-up). 5f74 can read container files (env holds SECRET_KEY, DB password) for any household user.
|
||||
Worst real: high.
|
||||
|
||||
## Fix
|
||||
Smallest: 2.7.0. TARGET: 2.7.2 (ghcr tags 2.7.0/2.7.1/2.7.2, no v). Same main: yes.
|
||||
Breaking (read 2.7.0, 2.7.1, 2.7.2): 2.7.0 migrated all auth views to the new frontend; REMOVED settings SOCIALACCOUNT_ONLY, SOCIALACCOUNT_LOGIN_ON_GET, SOCIALACCOUNT_AUTO_SIGNUP (none in our compose); REMOVED api-token-auth/ endpoint; new ACCOUNT_EMAIL_VERIFICATION default "optional"; ENABLE_SIGNUP also blocks social sign-up. 2.7.0/2.7.1 broke invite links on instances with sign-up disabled (fixed 2.7.2: "InviteLinks not working on pages with disabled signup") — our household path, so 2.7.0/2.7.1 must be skipped.
|
||||
Lane: strict reading BIG_STEP (removed settings + removed endpoint + rewritten login pages). The operator could rule it SECURITY_FIX: none of the removed settings is in our compose. Do this only after a bench walk proves /accounts/login/ still answers (probe + healthcheck) and an invite link works on 2.7.2 — unsure until measured.
|
||||
## Classifier note
|
||||
The watch matched only GHSA-5p9v in the 2.7.0 notes; the same body names 8 of our GHSAs — match every GHSA id in the body. cqj3: check release notes below the pin before flagging an unreadable range.
|
||||
@@ -0,0 +1,20 @@
|
||||
# termix — triage (group C, 2026-10-27)
|
||||
Pin: ghcr.io/lukegus/termix:2.8.0 (server image only). setup_gate + signup_block (/users/create) + ALLOW_REGISTRATION=false after setup. No X-Forwarded-For strip middleware (unlike paperless/sparky R-753).
|
||||
|
||||
## Version line
|
||||
2.8.0 -> 2.9.0/2.9.1/2.9.2 -> 26.10.0 (2026-10-10, "Termix now uses calendar versions"). 26.10.0 notes: "Downgrading to 2.8 is no longer supported. A 2.8 install has to start 2.9 once before upgrading" => a required intermediate step. ghcr.io/lukegus/termix tags read 2026-10-27: 2.9.2, 26.10.0..26.10.5, plus 26.10.5-minimal / -full variants (26.10.5: default image ships the most-used plugins).
|
||||
|
||||
## Notices (12)
|
||||
NOT-A-FINDING (2): GHSA-frx8-qqgg-7j7g (Termix Desktop embedded backend), GHSA-r9gw-3w87-mhh7 (Electron desktop client cert validation) — desktop client only, we ship the server image.
|
||||
REAL (10), all `< 26.10.0` (some `>= 2.6/2.7`), fixed 26.10.0:
|
||||
- Strangers (no login): GHSA-7j7m (low; login rate limit bypassed by rotating X-Forwarded-For — reachable, our route keeps the client XFF chain); GHSA-fj9w (high; webhook-trigger body injected into run_command shell — reachable only if a household user built such an automation); GHSA-hmv7 (high; read-only share guest types into owner's SSH session — needs a share link the owner handed out).
|
||||
- Any household user: GHSA-3q2m (high, cross-user nested automation), GHSA-rgf3 (high, cross-user SFTP session), GHSA-v3vp (high, Cloudflare ACME token in user export — only if admin set Cloudflare DNS ACME), GHSA-r7x4 (medium, Guacamole token for any target; no guacd in our stack), GHSA-wv2p (medium, Vault SSRF), GHSA-6gr3 (low, 2FA bypass — needs the password).
|
||||
- Admin-config dependent: GHSA-j7j4 (medium, LDAPS no cert check — only if LDAP configured).
|
||||
Worst real: high.
|
||||
|
||||
## Fix
|
||||
Smallest: 26.10.0. TARGET: 26.10.5 (newest stable; path 2.8.0 -> 2.9.2 -> 26.10.5). Same main: NO (2 -> 26).
|
||||
Breaking (read release-2.9.0..2.9.2-tag, v26.10.0..v26.10.5): 2.9.0 large API change for plugin system (mobile app >= 1.5.1); 26.10.0 features moved into plugins, calendar versions, TRUSTED_PROXIES added, no downgrade to 2.8, 2.9 must run once first; 26.10.2 compose no longer starts guacd; 26.10.3 sync moved to a plugin, layouts from a plugin; 26.10.5 image variants (default/minimal/full). 2.9.1/2.9.2 fixed OIDC-after-upgrade and a 100 GB/h disk-write bug (do not stop on 2.9.0/2.9.1).
|
||||
Lane: BIG_STEP (two-hop).
|
||||
## Classifier note
|
||||
Skip advisories whose package/summary is the Desktop/Electron client (frx8, r9gw). The 2.8 -> 26.10 jump is a calendar-version rename, not 24 majors.
|
||||
@@ -0,0 +1,21 @@
|
||||
# uptime-kuma — triage (pin louislam/uptime-kuma:2.5.5, the normal (root) image, not -rootless)
|
||||
Template: setup_gate: true; single-user app (the one account is the admin).
|
||||
|
||||
## Notices
|
||||
- GHSA-98hr-q8q8-5j23 rootless sudo privilege escalation — NOT-A-FINDING: affects only the `-rootless` image variants; we ship `2.5.5`.
|
||||
- GHSA-qjxc-h5jf-c7rj SSRF to cloud metadata (range `*`, no patch, "will not fix") — NOT-A-FINDING, decided by hand: the advisory itself says
|
||||
it is a deployment-platform issue for cloud IMDS (169.254.169.254); a Felhom box is home hardware with no metadata service, and the only
|
||||
account is the admin, who is meant to monitor internal URLs.
|
||||
- release:2.5.8 — REAL: GHSA-v2p3-6f5h-6hhf "[Admin Only] RCE" (details not public yet; severity unsure). Login: admin. Reachable: only with the
|
||||
household's admin login.
|
||||
- release:2.5.7 — REAL runtime fix: Node.js 22.23.4, rejects the leaked eMudhra CA.
|
||||
- release:2.5.6 — weak: "chore: Update dependencies" (no CVE named); it is also the release that fixes GHSA-98hr (rootless only). Treat as hygiene.
|
||||
|
||||
## Fix
|
||||
Smallest fixing the real item: 2.5.8. TARGET `louislam/uptime-kuma:2.5.8` (Docker Hub tag exists, no `v`). Same main (2): yes.
|
||||
Breaking (3 releases read 2.5.6..2.5.8): 2.5.8 DROPS TLS support for the TCP Port monitor — existing TLS TCP monitors silently become plain TCP
|
||||
monitors (a removed option + data conversion). Nothing else.
|
||||
Lane: SECURITY_FIX if the operator accepts the TCP-TLS removal as minor (Felhom ships no TCP-TLS monitors by default); strictly by the rule it is a
|
||||
removed feature → BIG_STEP. I lean SECURITY_FIX: admin-only RCE + CA distrust, and the removed option "never worked as expected" upstream.
|
||||
Classifier note: GHSA-98hr's package name is "Rootless Docker Image only" — the watch should skip it for non-rootless tags; GHSA-qjxc (range `*`,
|
||||
no patch, platform issue) should be filtered as permanent won't-fix.
|
||||
@@ -0,0 +1,32 @@
|
||||
# vikunja — triage (pin vikunja/vikunja:2.6.0, SQLite, single image)
|
||||
|
||||
Template: `setup_gate: true`, `signup_block` on /api/v1/register, registration switched off after setup. No OIDC, no
|
||||
Todoist/Trello/MS-To-Do migrator env (all off by default). Public behind Vikunja's own login.
|
||||
|
||||
## Notices (43 GHSA + 2 release hits)
|
||||
The 6 published 2026-10-03 with "no fixed version named yet" — GHSA-m687-p538-r5hp (high), -4hv6-xc92-j86g, -hjx8-qv73-f7cm,
|
||||
-pjr3-86v4-5p7w, -fmmf-xq98-g327, -fprf-r6rv-xg99 — have ranges ending `<= 2.6.0` and are exactly the "six security fixes"
|
||||
of v2.7.0: the vikunja.io 2.7.0 changelog page links all six GHSA ids. FIXED in 2.7.0. REAL for our 2.6.0.
|
||||
The 37 published 2026-10-22: range `<= 2.7.0`, patched 2.7.1 (2.7.1 changelog page links 41 GHSA ids).
|
||||
|
||||
NOT-A-FINDING (3):
|
||||
- GHSA-h8wj-3gwg-jjjg (low): release toolchain (xgo) pulled by mutable ref — project CI, not the product.
|
||||
- GHSA-wqjr-22r7-5437 (medium): Trello/Todoist/MS To Do migrations — those migrators need OAuth env, off in our template.
|
||||
- GHSA-xgw3-ccqg-f6ww (low): migration OAuth callbacks — same migrators, off.
|
||||
|
||||
REAL (40 GHSA + release:v2.7.0 + release:v2.7.1 = 42 / 45). Worst: high — GHSA-m687 (any localhost page can take the session:
|
||||
no attacker login, needs victim's browser), GHSA-hq66 (account deletion escalates read-only shares; any user), GHSA-5q33
|
||||
(webhook payloads bypass read auth; any user). Most others need any logged-in user. Low/no reach on a box: GHSA-9rfw/rp64/hrw2
|
||||
(file permissions/paths inside the container; we do not run `vikunja dump`), GHSA-frf4 (login CSRF, no OIDC here but
|
||||
form-login part applies).
|
||||
|
||||
## Fix
|
||||
Smallest fixing all: 2.7.1. TARGET `vikunja/vikunja:2.7.1` (newest stable; Hub tags 2.7.1, 2.7, 2, latest). Same main (2): yes.
|
||||
Breaking/migrations 2.6.0 -> 2.7.1 (read v2.7.0, v2.7.1 GitHub bodies + both vikunja.io changelog pages):
|
||||
- 2.7.1 "Things to check": API token permission keys renamed (existing tokens auto-migrated); access log writes route template;
|
||||
new limits 100 manual / 50 filter buckets per view, migration.maxitems 100000; v2 attachment download ignores preview_size.
|
||||
- 2.7.1: stored files + SQLite no longer world-readable (permission tightening — check the backup path reads them as root; unsure).
|
||||
- 2.7.0: link-share management now needs project admin; frontend dropped v1 API client. No env rename, no file layout change.
|
||||
None is a data/file conversion or removed config. Lane: SECURITY_FIX.
|
||||
Classifier note: "no fixed version named yet" was wrong for 6 notices — a range with an upper bound `<= 2.6.0` published after
|
||||
v2.7.0 means "fixed in the next release"; the classifier should read the range upper bound (and the release body links) before saying no fix.
|
||||
@@ -0,0 +1,34 @@
|
||||
# wanderer — triage (pins flomp/wanderer-web:v0.20.0, flomp/wanderer-db:v0.20.0; meilisearch v1.36.0 untouched)
|
||||
Upstream repo now open-wanderer/wanderer (images still flomp/*).
|
||||
Template: NO gate (R-714: web calls its DB via the public name); signup_block + after_setup SIGNUP_CLOSED. PocketBase (wanderer-db) is
|
||||
published on its own public subdomain (SUBDOMAIN_DB).
|
||||
ActivityPub federation: ON — wanderer has no switch to turn it off (docs run/environment-configuration.md at v0.21.2 lists none;
|
||||
federation is core). Inbound inbox is reachable by any remote actor through the public web subdomain.
|
||||
|
||||
## Notices (all 9 REAL — every range covers v0.20.0)
|
||||
| GHSA | sev | login | fixed |
|
||||
|---|---|---|---|
|
||||
| fprh-3pp9-68m9 AP Create/Update no ownership check + unsanitized HTML (incomplete fix of xcwc) | critical | none (remote actor) | v0.21.2 |
|
||||
| xcwc-jhv2-w4h6 AP Delete without ownership check — remote actor deletes any local trail/list | high | none | v0.21.0 |
|
||||
| mr29-2qg5-m4fw inbox trusts client X-Forwarded-Path → forge local inbox route | high | none | v0.21.0 |
|
||||
| 8j93-xvwx-jjg3 SSRF guard bypass via IPv6 transition addresses | high | none/any user (follow) | v0.21.0 |
|
||||
| j9m4-8qwf-jvx6 SSRF via AP list image attachments | high | none | v0.21.2 |
|
||||
| 3xp7-7492-j2q6 SSRF via AP attachment URLs (range <=v0.21.1) | medium | none | v0.21.2 |
|
||||
| vprp-gr6m-j375 blind SSRF via inbox delivery | medium | none | v0.21.2 |
|
||||
| 332v-mq7g-5hqf comments/summit_logs/trail_like author not bound | medium | any user | v0.21.0 |
|
||||
| vj82-xj83-jp85 waypoints createRule omits trail ownership | medium | any user | v0.21.0 |
|
||||
Reachable on a box: YES (no gate; federation always on; sign-up closed after setup limits the "any user" ones to household accounts).
|
||||
release:v0.21.0 and release:v0.21.2 hits — REAL (they are these GHSA fixes). v0.21.1 also has unlisted security fixes (stored XSS, owner change).
|
||||
|
||||
## Fix
|
||||
Smallest fixing all: v0.21.2. TARGET `flomp/wanderer-web:v0.21.2` + `flomp/wanderer-db:v0.21.2` (Docker Hub tags verified; NOT the `-app` variants
|
||||
unless the mobile app is wanted). Same main (0): yes.
|
||||
Breaking (3 releases read: v0.21.0, v0.21.1, v0.21.2):
|
||||
- v0.21.0: NEW REQUIRED env `POCKETBASE_PROXY_SECRET`, same value on db and web (missing → inbound federation rejected); new deploy secret needed.
|
||||
- v0.21.1: first-start migrations clean stored rich text and tag names; text over field length is SHORTENED and a downgrade does not restore it
|
||||
(lossy data conversion); web now forwards visitor IP; `ADDRESS_HEADER` semantics changed; Hammerhead plugin bundle manual update.
|
||||
- v0.21.2: upstream says bind PocketBase to 127.0.0.1:8090 (our template publishes it on a public subdomain — the web UI "does not need
|
||||
port 8090" any more, so the db route could be dropped, but that is a template redesign); BODY_SIZE_LIMIT default 2G (we set Infinity, still
|
||||
allowed); AP deliveries need signed digest + date within 1 h.
|
||||
Lane: BIG_STEP (same main version but a new required secret + lossy migration + template change).
|
||||
Classifier note: none (ranges correct). Note fprh is an incomplete-fix of xcwc; 0.21.0 alone is not enough.
|
||||
@@ -0,0 +1,26 @@
|
||||
# wishlist — triage (group D)
|
||||
Pin: ghcr.io/cmintey/wishlist:v0.67.1. Gates: setup_gate + signup_block (/signup) + app sign-up switch closed by command.
|
||||
|
||||
## release:cmintey/wishlist@v0.69.0 — REAL, app security fixes + Node runtime
|
||||
Read the PR diffs:
|
||||
- PR #818 "remove reset token exposure": in v0.67.1 `src/routes/forgot-password/+page.server.ts` the form action creates
|
||||
a reset token for ANY existing e-mail and RETURNS it in the action result (`return { success: true, token }`). The
|
||||
action runs whether or not SMTP is enabled (only the page UI hides the form). A stranger who knows/guesses a user's
|
||||
e-mail POSTs to /forgot-password and receives the token -> /reset-password -> account takeover (admin included).
|
||||
Severity: CRITICAL (my rating; no GHSA published yet). Login: none. Reachable: YES — after the setup gate opens the
|
||||
app is public; signup_block covers only /signup. (Read from source, not tested live.)
|
||||
- PR #817 "validate list ownership on modifying APIs": any logged-in user could PATCH other users' lists/items (IDOR).
|
||||
Medium; login: any user.
|
||||
- PR #832 admin "clear sessions" action was not implemented. Low; admin.
|
||||
- Node.js Oct 2026 CVEs (base node:24-slim re-pinned, PR #829). Runtime; SvelteKit node adapter does not inflate bodies.
|
||||
## release:cmintey/wishlist@v0.68.0 "nodemailer v10 [SECURITY]" — NOT-A-FINDING
|
||||
GHSA-6vj9-mwq6-2f5v: process-global DNS cache leaks TLS servername across multiple SMTPS transports (multi-tenant).
|
||||
Wishlist uses one transport; our template sets no SMTP. Fixed anyway by the target.
|
||||
|
||||
## Fix / target
|
||||
Smallest fix = TARGET: `ghcr.io/cmintey/wishlist:v0.69.0` (ghcr tag exists; `v` prefix matches pin). Same main: yes (0).
|
||||
Breaking: none found (read v0.68.0, v0.69.0): entrypoint now `exec node build` (still runs migrate+seed+db:patch first);
|
||||
pnpm 12 via corepack; prisma migrations auto; manager/owner permission semantics changed (#819). Our healthcheck/command
|
||||
need only `node` + node:sqlite — still present (node:24-slim).
|
||||
Lane: SECURITY_FIX — urgent.
|
||||
Classifier note: the v0.69.0 summary is a URL fragment; it should quote the "## Security" paragraph. Hit itself is right.
|
||||
@@ -128,7 +128,7 @@ stopping line that lies.
|
||||
|
||||
| ID | Category | Sev | What | State | Blocked on | Next action | Owner |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| **R-1306** | Apps & catalog | P2 | **The first security-watch run: 27 catalog pins carry published notices that affect the version we pin** (89 notices; the list with our version and the fixed versions: `audits/security-watch-2026-10-26/ADVISORIES-2026-10-26.md`). Several fix only in a NEW major (Jellyfin 10.11.11 → 12.0; Gokapi 1.9.6 → 2.x; Seerr 2.7.3 → 3.x); some name no fix yet (SparkyFitness); some are release notes naming a CVE (Grafana, BookStack, PrivateBin …). The seed mailed none of them (R-1303). | OPEN — filed 2026-10-26 | the operator's order of triage | worst first through the security-fix lane (B23): read each notice against how the app is deployed, then a ladder step or a re-pin | CC |
|
||||
| **R-1306** | Apps & catalog | P2 | **The first security-watch run: 27 catalog pins carry published notices that affect the version we pin** (89 notices; the list with our version and the fixed versions: `audits/security-watch-2026-10-26/ADVISORIES-2026-10-26.md`). Several fix only in a NEW major (Jellyfin 10.11.11 → 12.0; Gokapi 1.9.6 → 2.x; Seerr 2.7.3 → 3.x); some name no fix yet (SparkyFitness); some are release notes naming a CVE (Grafana, BookStack, PrivateBin …). The seed mailed none of them (R-1303). | OPEN — filed 2026-10-26; **TRIAGED 2026-10-27** (with the key: 35 app pins in 32 apps): 15 apps go by the lane, Wishlist + BookStack as normal steps (no notice id), 11 need a big step, 5 are NOT-A-FINDING — `audits/security-app-updates-2026-10-27/TRIAGE.md` | the operator's order of triage | worst first through the security-fix lane (B23): read each notice against how the app is deployed, then a ladder step or a re-pin | CC |
|
||||
| **R-1091** | Apps & catalog | P3 | **Catalog copy that is wrong or stale at the pinned tag, found writing the guides — each needs an operator word or a live check, so none was changed tonight.** From source at each app's tag (evidence per app in `audits/app-guides-2026-10-15/B/`): (1) and (2) **DONE 2026-10-16** (operator decision D12: reword): calcom's use case now names Apple Calendar or a CalDAV calendar instead of Google/Outlook, and bentopdf's tagline and use case say the browser does the work and the file stays on the device (catalog CHANGELOG 2026-10-16); (3) **sabnzbd**, **nzbget** use_cases say Radarr/Sonarr/Jellyseerr hand them jobs — the box wires only qBittorrent and Transmission (`mediawire.go`), and a hand link needs a path mapping; (4) **onlyoffice** first_steps 3–4 tell the household to wire Nextcloud by hand — the integration toggle does it (`internal/integrations/onlyoffice_nextcloud.go`); (5) **glance**, **homepage** first_steps send the household into config files in a Docker volume no household tool reaches; (6) **lubelogger** starts with only the „Dashboard" tab and in miles (shipped `appsettings.json`), so first step 3 cannot be done as written; (7) **home-assistant** first_steps promise auto-discovered devices — the app runs on a Docker bridge, where mDNS/SSDP were measured deaf (spike R-6); (8) **homebox** and **gitea** `add_people` name menus that moved or read differently at the tag; **bookstack** `default_creds` still says `admin@admin.com / password`, which after_install replaces; **dawarich** names the API key's page „Settings" (source suggests the account page); **code-server** says „install your tools" with no sudo; **komga** names the discontinued Tachiyomi; **seerr** `docs_url` points at Overseerr; **wanderer**'s comment still says it cannot close sign-up (R-714 is fixed in the same file); (9) **nzbget** and **grafana** deploy-field descriptions say the password can be changed later — nzbget re-applies its env password at every start and grafana ignores the field after first start (R-1086 is the qBittorrent/Transmission side). | OPEN — filed 2026-10-15 | — | Live-check (5)–(7) and (9) on 9202; fix (3), (4), (8) as copy with the freeze re-admitted; re-run the guide label check for any app whose copy moves | CC |
|
||||
| **R-1308** | Apps & catalog | P3 | **14 catalog pins use a floating tag** (`redis:7-alpine`, `postgres:16-…`, `mariadb:12.3`, `nginx:…`): there is no exact version to match a notice's range against, so the security watch (R-1303) lists them FLOATING and matches nothing. `audits/security-watch-2026-10-26/ci-seed.log` (FLOATING) | OPEN — filed 2026-10-26 | — | pin the sidecars to exact versions where the engine allows (the image-pins gate today accepts a major tag) | CC |
|
||||
| **R-1092** | Apps & catalog | P4 | **Three apps show no guide: plant-it and home-assistant carry one HIDDEN (`checked_version: ""`), emby has none.** plant-it: `lifecycle: abandoned`, and its pinned image does not exist upstream, so there is no screen to check labels against. home-assistant: its frontend follows the browser language and the Hungarian strings are fetched at build time, not kept in git, so the Hungarian labels cannot be checked against source (the draft is written; the shipped frontend in the image could check them). emby: its server's web UI is in no public source at 4.11.0.4. Evidence: `audits/app-guides-2026-10-15/B/`. The other 62 templates show a checked guide (controller ≥ 0.315.0). | OPEN — filed 2026-10-15 | — | home-assistant: check the Hungarian labels against the frontend files in the pinned image (read-only, on a box running it), then set checked_version; emby: label-check against the image's own web files the same way; plant-it: nothing while abandoned | CC |
|
||||
@@ -233,7 +233,7 @@ stopping line that lies.
|
||||
| **R-1275** | Storage & devices | P4 | **An English household sees the drive names in Hungarian** on the install page (and wherever a storage label shows): „Belső tárhely — 52.0 GB free (default)”, „Külső tárhely (hdd_1)” (catalog sweep 2026-10-24, `audits/catalog-sweep-2026-10-24/navidrome/page-install-en.txt`). The label is stored once, in Hungarian, when the drive is found (`felhom-controller/controller/internal/settings/settings.go` `InferStorageLabel`); a household may rename it. | OPEN | — | Render a label that still equals the inferred default in the reader's language; a test per language | CC |
|
||||
| **R-1276** | Storage & devices | P4 | **„Remove with data” leaves the app's empty parent folder** (`<drive>/appdata/<app>`) when the template binds a subfolder: Grimmory, RomM, Paperless-ngx (catalog sweep 2026-10-24; 4 KB each; the bound folders were removed). Harmless (empty, not counted as old data), untidy for a household that browses the drive. | OPEN | — | Remove the parent when it is empty after the bound folders go; a test | CC |
|
||||
|
||||
## Security & access — 29 rows (P1 2, P2 5, P3 15, P4 7)
|
||||
## Security & access — 30 rows (P1 2, P2 5, P3 16, P4 7)
|
||||
|
||||
| ID | Category | Sev | What | State | Blocked on | Next action | Owner |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
@@ -248,6 +248,7 @@ stopping line that lies.
|
||||
| **R-1141** | Security & access | P3 | **`felhom-host-install --rotate-recovery` exists only as part of a full installer re-run, which also reinstalls the vouched agent and the root files.** On a box running a newer agent than the vouched one (demo-hp on the candidate, 2026-10-17) it would move the agent back; on a household box it is a much larger act than a password change. The 2026-10-17 rotation therefore ran the installer's own `step_break_glass` ALONE (`audits/agent-allowlist-rotation-2026-10-17/P3/`). | **NARROWED 2026-10-18 — built on `main`, not published.** `felhom-host-install.sh --rotate-recovery-only` runs step 4b alone (felhom.eu `7d64038f`): reads the hub, host id and host key from the agent config, refuses byo and every other mode flag, asks the hub's `/healthz` before the password changes, never touches the agent or root files. The default install path is unchanged in behaviour (harness verdicts and 9 transcripts identical old vs new; demo-hp `--preflight-only` identical; `--rotate-recovery-only --dry-run` on demo-hp changed nothing). `step_break_glass` moved, byte-identical, ahead of the argument parse. `break-glass.md` §5 points at it. Publishes only with the next `installer-v…` tag. | the next installer tag | Cut the next `installer-v…` tag (with the other untagged installer changes); close | CC |
|
||||
| **R-1258** | Security & access | P3 | **ep0's iperf3 line-test server takes any tunnel peer's test: one box (root on its host) can keep it busy for the fleet or ask a long reverse test that fills ep0's uplink.** Found 2026-10-24 (SEC-2 X2): `felhom.eu/scripts/ep0-iperf3/felhom-iperf3.service:17` — no authorized users, no server-side duration or rate cap; one client at a time (`felhom-agent/internal/linetest/iperf.go:263-264` → `busy`; 6 tries a day). Static (no ep0 change in this run). | OPEN | — | per-box iperf3 users or server-side caps, tried on a scratch VM first | CC |
|
||||
| **R-1307** | Security & access | P3 | **Packages inside our own images are not watched** — the Debian packages of the controller image, the Alpine packages of the hub and Samba images (Samba's version is whatever Alpine 3.24 ships). The security watch (R-1303) reads only the base image's point release (BEHIND); Debian's DSAs and Alpine's secdb are not read. `audits/security-watch-2026-10-26/SPIKE.md` „cannot see" | OPEN — filed 2026-10-26 | — | add Alpine secdb (machine-readable JSON per release) and Debian's tracker for the packages the images install, or a scanner run on the built images in CI | CC |
|
||||
| **R-1311** | Security & access | P3 | **Termix (catalog 2.8.0): a stranger can get round the login rate limit by writing their own X-Forwarded-For (GHSA-7j7m-85p4-2cpm), and our template keeps that header** (docmost and paperless strip it, R-753). The upstream fix needs Termix's big step (2.8 → 2.9.2 → 26.10.5). No box runs Termix (hub 2026-10-27). `audits/security-app-updates-2026-10-27/TRIAGE.md` | OPEN — filed 2026-10-27 | the operator: a template change (strip the header like R-753, so every visitor shares the tunnel's one address and the limit can lock the household out — the Grimmory shape, R-775) or wait for the big step | the pick in `PICKS.md`; or the big step | CC |
|
||||
| **R-955** | Security & access | P4 | **The cross-box check of the hub API is done in source and tests but not fully proven: if a later check masks a missing id check, a box's key could read or change another box's hub record without any test noticing.** Read 2026-10-12: every box-facing `/api/v1` route takes the box from its own key or refuses a different id; 14 routes already had a refusal test, 5 got one (`crossbox_refusal_test.go`). Left: red-prove the 4 new tests that were not red-proved (as the restore-directive one was), and the live read-only check with one demo box's key against the other demo box's id. | OPEN — filed 2026-10-12 by the security review | — | Red-prove the 4 tests; run the live GET check on the two demo boxes | CC |
|
||||
| **R-924** | Security & access | P2 | **The operator signing keys exist only on DooPlex, with no passphrase and in no backup — a loss of DooPlex means no box ever accepts a signed agent update, config bundle or OS step again without an on-site re-enrollment.** MEASURED 2026-10-09: `/mnt/5_hdd/felhom.eu/felhom-op-operational`, `felhom-rec-recovery`, `felhom_op_ed25519` (0600 `kisfenyo`); `ssh-keygen -y -P ''` opens all three (no passphrase); `/mnt/5_hdd/felhom.eu` is in no backup set, the off-site job does not carry them. `04` §1 says the operational key is "passphrase-protected" and the recovery key "kept offline" — today neither holds (custody ruling 1 of 2026-09-16 put both on DooPlex for this phase; `04` §3.1). Both keys share one fate, so the cold key cannot do its one job (re-pin after losing the operational key). `runbooks/total-loss-of-dooplex.md` S6. | NARROWED — **2026-10-23 (D32):** S6a/S6b are on the current sheet. LEFT: the operator prints it. **NARROWED 2026-10-09 — operator ruling: option A** (print both AND copy them). The three key files and their public halves ride the nightly encrypted DooPlex→ep0 copy (`scripts/dooplex-offsite/`, a missing key refuses the push); the Sunday restore test proves each private key still derives its own public half (never printed). **LEFT:** the operator prints S6a/S6b (`runbooks/break-glass-sheet.md`); the keys still have no passphrase (custody ruling 1 of 2026-09-16 stands until the first sale). **2026-10-23 night — survey (`audits/dooplex-survival-2026-10-22/PLAN.md`, G2):** the three key files are on `sda1`, the same disk as DooPlex's local backup tree; their only off-box copy is the S1-encrypted nightly one. Passphrase: unchanged by the custody ruling. | operator: print | Operator: print the two keys; then close | operator |
|
||||
| **R-132** | Security & access | P3 | **`curl -w '%{redirect_url}'` reconstructs the request URL WITH its basic-auth credential** — so a `-u ":$HUB_PW"` call that never put the password in a URL still printed it **Merged 2026-10-05 from R-350 (duplicate):** (1) 2026-08-20 occurrence: POST /configuration/artifacts answers 303; leak lives only in the CC transcript under ~/.claude/projects/ on DooPlex, not in git/evidence (checked then). (2) `-v` and `--libcurl` also re-render the credential, not only %{redirect_url}; confirm redirects with %{http_code} + follow-up GET. (3) Rotation path: hub /configuration form (current_password/new_password/confirm_password); DB override wins over ConfigMap (break-glass); CC can rotate file-to-file without printing (operator-present-one-time-secrets) if asked. | **NARROWED 2026-10-20 — the rotation is DONE:** the operator changed the hub password on 2026-10-15 and the `HUB_PW` line is gone (`audits/hub-tokens-2026-10-15/C153-live.txt:18`; CC uses its own token since hub 0.152.0). **Left, the operator's:** should the break-glass `password_hash` in `manifests/hub.yaml` (a public repository) be emptied or replaced? The DB override wins at login, so the old hash no longer opens the hub. **WAITING-ON-OPERATOR** — **ACTION: rotate `HUB_PW`** **Folded R-580 2026-10-03** (the same `curl -w %{redirect_url}` credential echo, seen again 2026-09-18). **Note 2026-10-12 (security review):** `manifests/hub.yaml` also carries the hub login's bcrypt hash in this public repository (the break-glass field); when `HUB_PW` is rotated, decide whether that field should stay empty. | the operator's word on the `manifests/hub.yaml` hash field | Happened on 2026-07-31 while red-proofing the R-120 gate: the hub operator password was written to the session transcript by the write-out format, not by the request. `-u` is safe; the *reporting* was not. Rule: read the redirect from `-D -` and grep `^Location:`, never `%{redirect_url}`, on any authenticated call. Rotate the hub password (`/configuration` → Login password; ConfigMap `auth.password_hash` is the reset path) and update `~/.config/credentials` | Viktor |
|
||||
@@ -287,12 +288,13 @@ stopping line that lies.
|
||||
| **R-1285** | Box system & updates | P4 | **D43's removal of our SSH drop-in from a BYO host happens one bundle LATE: the bundle run that delivers agent 0.165.0 is planned by the box's OLD (0.164.0) wrapper, which writes the drop-in as before („same"), and only then replaces itself.** Measured 2026-10-25 on the BYO test host (VM 9371 on demo-hp, `Tester4-f967d4`; attended release run): 0.164.0 day-0 → signed `agent_update` + `agent_config_update` 0.165.0 → the planted drop-in still there; a second `agent_config_update` (same bundle) → `BUNDLE REMOVED … (ours, on a BYO host — D43)`, nothing written, `sshd -T` the owner's own `permitrootlogin yes` (`audits/release-2026-10-26/byo/byo-proof.txt`). No box is affected today (the fleet's only BYO host is this test host); a fresh BYO install on ≥ 0.165.0 runs the new wrapper from the start. | **VERIFY** — 2026-10-26: agent `b1bc63d` (unreleased) — the new agent runs the bundle-policy pass once right after its self-update commits (`selfupdate.SetOnCommitted`); test in the real order (commit, then one pass), red-proved. **Not live:** only a box coming FROM 0.164.0 discriminates (0.165.0's wrapper already applies D43), which needs a signed downgrade chain on a BYO box — the live proof rides the next agent release. **Earlier:** **OPEN** — 2026-10-26 (agent 0.166.0 released, attended run): the policy pass is wired, but in the normal delivery it does NOT run: the box gets `agent_update` and `agent_config_update` in ONE pass, and the bundle job runs in the OLD process (demo-hp: pid 1966780, agent 0.165.0, bundle 09:03:07–09:03:09 CET; the restart into 0.166.0 at 09:03:10) — no `bundle policy pass` line on any of the three boxes. So a BYO host coming from 0.164.0 still loses our drop-in one release late. The night proof (`audits/night-2026-10-25/rig/r1285-live.txt`) ran a bundle under an agent that was ALREADY 0.166.0-code, so it did not cover this order. No BYO host is in the fleet today. Fix options: the agent runs the pass once at start-up after `update committed`; or the release procedure sends the bundle job only after the commit. **Earlier state:** **VERIFY** — fixed on main 2026-10-25 night (agent `abcc1e6`), waits for the agent release + the vouch: the agent runs the wrapper's `bundle-policy` pass after every install (red-proved, `redproof-r1285.txt`). **Live on the rig in ONE signed run** (BYO host, staged as upgraded from 0.164.0: the new agent by hand, the old 0.164.0 wrapper on disk, our drop-in planted; one `agent_config_update` of a test bundle): the old wrapper installed the bundle and replaced itself, then „BUNDLE POLICY REMOVED … (ours, on a BYO host)", `sshd -T` the owner's own `permitrootlogin yes` (`rig/r1285-live.txt`); the test package deleted from the registry after. **Earlier state:** OPEN | — | either the wrapper plans again after it replaced itself (one agent change + a test that a 0.164.0→0.165.0 bundle on a BYO record removes our copy in ONE run, red first), or the release procedure sends a BYO box's config bundle twice; until then a BYO box upgraded from ≤ 0.164.0 keeps our drop-in until its next bundle | CC |
|
||||
|
||||
|
||||
## Monitoring & notifications — 24 rows (P2 1, P3 16, P4 7)
|
||||
## Monitoring & notifications — 25 rows (P2 1, P3 17, P4 7)
|
||||
|
||||
| ID | Category | Sev | What | State | Blocked on | Next action | Owner |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| **R-1261** | Monitoring & notifications | P3 | **The R-1250 line hold (committed, NOT released): three edges before it ships (review round 2, HUNT-4 H4–H6).** Two seeders behind one uplink: the hold takes only the first, so the test is refused „not quiet” every 15 min in the Tuesday window and never counted (`felhom-controller/controller/internal/upwatch/linehold.go:155-160`; agent `internal/linetest/linetest.go:379-381`); a hold record of an app removed while held is never cleared and the 50 % rule never runs again (`linehold.go:106-108`; `upwatch/service.go:149`); a qBittorrent alt-speed flip during the hold leaves 1 KiB/s stored (`explain.go:175`; `linehold.go:127-128`). | **VERIFY** — RELEASED in controller v0.344.0 (global floor 2026-10-26 09:07:47Z, every live box on 0.344.0); the live test with a seeding box is Tuesday 10:00–16:00 (R-1250's dated check). **Earlier:** **VERIFY** — fixed on main 2026-10-25 night (controller `a79a292`), waits for the controller release (before any household gets agent 0.165.0 by signed update): every running seeder held, a removed app's record dropped, qBittorrent's slot named (`up_limit`/`alt_up_limit`). Red-proofs `audits/night-2026-10-25/redproof-r1261.txt`. **Live on the night's rig** (BYO VM, agent 0.165.0, rc.1, two seeders): both held, 94.8 Mbit/s, both limits back; a speed-mode switch mid-test left no 1 KiB/s (`rig/hold-watch*.txt`); the removed-app case by test only. **Earlier state:** OPEN — **now in controller 0.343.0 (released 2026-10-25); the three edges act only on a box whose agent is ≥ 0.165.0 (it alone reports `waiting_for_quiet`) — fix before any household gets agent 0.165.0 by signed update** | — | before the next controller and agent release: hold every running seeder; clear a record whose app is gone; read the mode | CC |
|
||||
| **R-1262** | Monitoring & notifications | P3 | **The upload watch treats ANY viewer as an explanation for any amount of upload, so a hacked Plex can send freely while one family member watches.** Found 2026-10-24 (SEC-1 X1): `felhom-controller/controller/internal/upwatch/watch.go:275,299`; `08` §9 states the rule, its limits list did not name this case. | OPEN | — | propose a cap (viewers × a bitrate ceiling) for the operator's R-1244 design; `08`'s limits list names the case meanwhile | CC |
|
||||
| **R-1310** | Monitoring & notifications | P3 | **The security watch (R-1303) flags notices that do not apply and misses fixes that do — measured by reading all 38 flagged pins by hand on 2026-10-27.** False: advisories of ecosystem `actions` (Home Assistant's CI), of another package in the repo (Gitea's runner), with a hostname or ≤-old range (cal.com 2023/2024, Grafana 2022), for the desktop/Electron client (Termix), for the rootless image only (Uptime Kuma); a release hit on a word (Dawarich „no longer receives security fixes", Rallly v4.16.0). Wrong „no fix": Vikunja's six (range `<= 2.6.0`, fixed in 2.7.0), karakeep-chrome (154/156 exist). Missed: Tandoor 2.7.0 names 8 GHSA ids (1 matched), Dawarich 1.16.0 (2FA, export deletion), Wishlist v0.69.0 (critical, no GHSA). BEHIND reads linuxserver `26.09.20260929` as newer than 26.09.2; Seerr follows the renamed-away `fallenbagel/jellyseerr`. `audits/security-app-updates-2026-10-27/TRIAGE.md` NOT-A-FINDING list and `triage-notes/` | OPEN — filed 2026-10-27 | — | teach `security_watch.py`: skip ecosystem `actions` and a package that is not the pinned one; read an upper-bound-only range as „fixed after"; match every GHSA id a release body names; ignore `YY.MM.YYYYMMDD` tags; repoint seerr to `seerr-team/seerr`; each with a test seen failing | CC |
|
||||
| **R-1020** | Monitoring & notifications | P4 | **`app_repaired_after_crash` reports a duration of 0 s, and the controller log says „in 0s".** `RunAfterUncleanBoot` sets `res.Duration` in a deferred func after the result is already returned (no named result), so the caller sees 0; the `app.yaml` record is right (10,172 ms on demo-hp 2026-10-14, `audits/immich-repair-2026-10-14/D/`). Small, but the controller release for this session is spent (v0.311.0). | **OPEN** — filed 2026-10-14 | — | CC: a named result (or set the duration before return), with a test on the returned value; ride the next controller release | CC |
|
||||
| **R-528** | Monitoring & notifications | P2 | **[P2-MEDIUM] Docker does not report an OOM kill inside a Felhom LXC guest: `OOMKilled` stays false and no `oom` event fires, so the v0.243.0 OOM line is not proven live.** MEASURED 2026-09-15 on scratch 9202 (Docker 29.8.0): Paperless capped at 128M restarted 11 times with `OOMKilled=false` and zero `docker events --filter event=oom`; a memory hog inside the running container was killed (rc 137) with the same silence (`E2-oom-signal-measure-9202.txt`). BIGNIGHT VM 333 did read `oomkilled=true`, so the shape differs by case. **Fix shape:** the agent reads the guest container cgroups' `memory.events oom_kill` counters (host-side, reliable), or the controller alarms on a restart-count trend **RE-MEASURED 2026-09-16 on the DRILL box (fresh install, nested VM 334, Docker in an LXC guest, controller 0.243.0), so the finding is not a property of one machine:** the Paperless webserver was capped at 128 M with `docker update --memory`; it restarted 9-10 times, and all three signals stayed silent - `OOMKilled=false` on every inspect, `docker events --filter event=oom` EMPTY for the whole window, the container's cgroup not visible from inside the guest, and `dmesg` unreadable there. Identical to scratch 9202. So the v0.243.0 OOM line cannot fire on ANY Felhom box as shipped, on either host. Evidence: `audits/evidence-drill-0243-2026-09-16/phase2-m1-oom.txt`. | **WATCHING — DESIGN WRITTEN 2026-10-26 night (the brief's Part 7: build only if time is left; it was not built — the line test and the attended release came first).** The host-side counter EXISTS and is readable (read on demo-hp 2026-10-26): `/sys/fs/cgroup/lxc/<vmid>/ns/system.slice/docker-<64-hex id>.scope/memory.events`, line `oom_kill N`. **Design:** (1) agent: a read-only collector (no root CLI — a sysfs read under the agent's own rights; if not readable, the existing sudoers fence gets one read-only `Cmnd_Alias`) that, for each guest in the `felhom` pool, globs those scopes and keeps `{container_id: oom_kill}`; served on the guest's own local API as `GET /guest/oom-kills` (`withGuest`, the guest's containers only). (2) controller: the 30-s dead-app scan asks once per pass; a RISE of a container's counter = an OOM kill whatever Docker's `OOMKilled` says → the existing `app_oom` line (R-636's per-run grain), `source: cgroup` in the details. An agent without the route = today's behaviour. (3) Tests: a fake cgroup tree (agent), a rising counter → one `app_oom` (controller, red-first). (4) Live: 9202, a throwaway app capped at 64M with a memory hog: the counter rises, `app_oom` names the container while `OOMKilled` reads false. ~1 day, two repos, one agent release. **Earlier:** WATCHING — **2026-10-12: the built part is released** (agent v0.150.0 carries the Docker-approval memory-kill check; the boxes run 0.154.0; hub 0.140.0+ requires a passing `oom_check` before a Docker set is approved). Per decision 157 nothing else is built; the row watches for a box whose Docker reports a false OOM flag. Dated look: 2026-11-12. **READY — rank P2-MEDIUM; owner: CC** **2026-09-17 (chaos night): an OOM WAS detected on a fresh box, and named precisely.** On `tester-1-022354` (controller 0.245.0, guest 9201, 6 GB RAM) immich’s Postgres was killed by the memory limit during its reverse-geocoding import, and the controller pushed `app_oom` (warning, operator-only): „Alkalmazás memóriája elfogyott: immich (immich-postgres) — egy folyamatát a memóriakorlát leállította” — naming the app AND the exact container. The visible consequence was `write CONNECTION_CLOSED immich-postgres:5432` and twelve restarts of immich-server. So on THIS box the OOM scan works and was the fastest route to the diagnosis; recorded here rather than filed as a new row. Evidence: `audits/evidence-chaos-night-2026-09-17/round-2.txt`. **2026-10-05 (burn-down night): a one-page design proposal (no code) is in `audits/night-burndown-2026-10-05/design-R-528.md`** — for the operator. **2026-10-06: STOPPED BEFORE ANY CODE — the measurement contradicted the design** (decision 155 said A then C). On scratch 9202, Docker 29.8.2, the `OOMKilled` flag was TRUE in all four shapes tried: a child process killed while the container kept running (`oom_kill` 0 → 3, flag true) and three main-process kills (exit 137, flag true); an `oom` event each time. The false flags of 2026-09-15 were on Docker 29.8.0. Cost read for the record: one exec read of 21 containers on demo-hp = 1.6 s. `audits/design-build-2026-10-06/`C/. **2026-10-06 18:24: operator ruling, option A (decision 157):** nothing is built; the row stays open as a WATCH for a box whose Docker reports a false flag. **Added:** a Docker engine set may not be approved until it reports a memory kill correctly on the boxes that ran it (built in this row's next session). **2026-10-06 (night): the Docker-approval memory-kill check is BUILT** — hub v0.140.0 (LIVE: the approval waits for a Line truncated
|
||||
| **R-1250** | Monitoring & notifications | P3 | **A qBittorrent that seeds all day is never line-tested, so it never gets the limit that exists for it.** The weekly test (R-1247) starts only after 10 minutes in which the host's uplink sent < 2 Mbit/s each minute; a seed at the line's speed keeps it busy through every window, so no test, no tested line, and no qBittorrent limit (D41 uses the tested line only). Found 2026-10-24 by reading the rule against the case it serves; not yet seen on a box (no test box seeds). **Due check moved 2026-10-27 → 2026-10-28 (2026-10-27 04:20Z, CC):** the measurement runs TODAY in the host's window (from 10:00 CET); on 2026-10-27 the gate would refuse every push until then. The result is recorded here today, and the line leaves the block. | **VERIFY — released 2026-10-25, the live proof is a dated check:** controller 0.343.0 (global floor 17:53Z) + agent 0.165.0 (vouched 18:38 CET) carry it; the real proof cannot run before the next due window — the agent starts a test only on its due Tuesday 10:00–15:59 local, and every box measured on 2026-10-24. **DUE 2026-10-27:** a throwaway qBittorrent on demo-hp seeding to DooPlex's qBittorrent (operator's yes 2026-10-25, about 30 minutes), from before the host's slot; read the agent's line value and the limit back. **Earlier: NARROWED 2026-10-24 — FIXED on main, not released** (brief 2026-10-24 Part 4, commit only): agent `29bcf44`+`1e087bb` (`waiting_for_quiet`, `POST /host/line-test/run`), controller `046b808` (`internal/upwatch/linehold.go`: record first, hold at 1 KiB/s, test, the exact old limit back; the start-up check after a kill; the 50 % rule waits). Red-proofs in both CHANGELOGs. **Live on demo-hp with a real seed** (10 Mbit/s to DooPlex's qBittorrent): refused `not-quiet` without the hold; held: uplink 0.02–0.16 Mbit/s, 94.2 Mbit/s, 56.8 s, back to 1 249 280 B/s exactly; a kill -9 mid-test left the record and the start-up check put the limit back (`audits/dooplex-alarms-2026-10-24/part4-r1250-live-proof.txt`). The live run used probes over plain HTTP (the pinned agent client is unit-tested, not live). | the next release train (agent ≥ 0.165.0 needs the operator's vouch) | Release agent + controller in the next normal train; on a seeding box read one Tuesday's `line test on request` line; then close | CC |
|
||||
|
||||
Reference in new issue
Block a user