58 lines
5.3 KiB
Markdown
58 lines
5.3 KiB
Markdown
# The 20 catalog apps with a bad runtime inside (R-1332) — where each one stands, 2026-10-28
|
|
|
|
HTTP2Shell (CVE-2026-111497): the Brotli decoder in Node.js (fixed 22.23.4 / 24.22.1 / 26.12.1; 20, 23, 25 get no fix)
|
|
and Python `brotli` (fixed 1.0.10 / 1.1.1 / 1.2.1). **Every version below was READ FROM THE IMAGE**
|
|
(`scripts/image_runtime.py`: the registry config, then the layers — never release notes); the candidates came from each
|
|
registry's tag list in the pinned tag's own shape (`rt-candidates.json`, `rt-candidates.txt`). The main version is the
|
|
first number of the tag (the ladder's rule; 0.x moves by the minor were lane steps on 2026-10-27, e.g. Homebox
|
|
0.26 → 0.27). „Runs" = what the image starts (its config) and, on a test box, `ps` in the running container
|
|
(`ps-test-boxes.txt`). The setup gate covers an app only until its first account exists; the family gate always.
|
|
|
|
**Fleet (2026-10-28):** three boxes report — demo-hp, Tester 1, demo-felhom; no household. 9202 is scratch.
|
|
|
|
## State 1 — a fixed release in the same main version: a security-fix step (8)
|
|
|
|
| App | Pinned → step | Runtime: pinned → step | Runs | Boxes | Walk |
|
|
|---|---|---|---|---|---|
|
|
| adventurelog | v0.13.0 → v0.13.1 (frontend + backend) | Node 26.3.0 → 26.12.1 | `node start.js` (SvelteKit server; `ps` on demo-hp) | demo-hp | batch 1 |
|
|
| ghost | 6.67.0-alpine → 6.73.0-alpine | Node 22.23.3 → 22.23.4 | Node (Ghost) | — | batch 1 |
|
|
| metube | 2026.09.29 → 2026.10.27 | py-Brotli 1.2.0 → 1.2.1 | Python (aiohttp) | — | batch 1 |
|
|
| papra | 26.6.2-rootless → 26.7.1-rootless | Node 26.4.0 → 26.12.1 | Node | — | batch 1 |
|
|
| zipline | 4.8.0 → 4.8.2 | Node 24.21.0 → 24.22.1 (Alpine brotli-libs 1.2.1) | Node | — | batch 1 |
|
|
| karakeep | 0.33.2 → 0.34.1 | Node 24.18.1 → 24.22.1 | Node | — | batch 2 |
|
|
| tandoor | 2.6.15 → 2.7.2 | Node 24.18.1 → 24.22.1 (Alpine nodejs 24.22.1-r0) | Python (Django) + Node in the image | — | batch 2 |
|
|
| dawarich | 1.15.3 → 1.19.0 (app + sidekiq) | Node 20.19.2 → **no Node in the image** (Debian libbrotli1 1.1.0-2+deb13u1) | Ruby (Rails) | — | batch 2 |
|
|
|
|
(Home Assistant 2026.9.4 → 2026.10.4 and Immich v3.2.4 → v3.3.5 went live this morning — catalog `b5b78f6`, `0158b50`.)
|
|
|
|
## State 2 — the fix needs a new main version: a row each, no step today (4 apps + 1 box program)
|
|
|
|
| App | Pinned → fixed in | Runtime | Runs | Gate | Boxes |
|
|
|---|---|---|---|---|---|
|
|
| homepage | v1.13.2 → v2.x (v2.7.0) | Node 22.22.3 → 24.22.1 | `node server.js` as root | family gate (always) | — |
|
|
| termix | 2.8.0 → the new numbering 26.10.x (26.10.5); 2.9.2 still Node 26.10.0 | Node 26.9.0 → 24.22.1 | Node | setup gate | — (D58: waits for its big step, R-1311) |
|
|
| wanderer | v0.20.0 → v0.21.2 | Node 22.23.1 → 22.23.4 | `npm run start` | — | none; **hidden since today (D59)** — its big step (R-1313's successor row) |
|
|
| seerr | jellyseerr 2.7.3 → upstream moved to `ghcr.io/seerr-team/seerr` (v3.5.1) | Node 22.18.0 → 22.23.4 | `pnpm start` (Node) | setup gate | — |
|
|
| filebrowser (a BOX program, not an app) | 1.5.8-stable → 2.0.2-stable | Alpine brotli-libs 1.2.0-r1 → 1.2.1-r0 | a Go binary that does NOT link libbrotli (`ldd`: musl only; no process maps it — all three boxes, `filebrowser-brotli.txt`); brotli-libs is there for libcurl | the controller's own route | all three boxes |
|
|
|
|
## State 3 — no fixed release exists (the watch keeps flagging them every night) (6)
|
|
|
|
| App | Pinned (newest) | Runtime | Runs | Gate | Boxes |
|
|
|---|---|---|---|---|---|
|
|
| actualbudget | 26.9.0 (26.10.0 still Node 24.21.0) | Node 24.20.0 | `node app.js` | setup gate | — |
|
|
| calcom | v6.2.0 (newest) | Node 20.20.0 (end of life — no fix on its line) + Debian 12 libbrotli1 1.0.9-2+b6 | Node (`start.sh`) | setup gate | — (R-1329) |
|
|
| calibre-web | v4.0.8 (newest) | py-Brotli 1.2.0 (+ Pillow's libbrotlidec 1.2.0, Debian libbrotlidec 1.1.0) | Python `cps.py` **loads all three** (its `/proc/<pid>/maps`, read from the guest — `calibre-web-brotli.txt`; a morning line here said „not loaded" from the process list: wrong, corrected the same day). The Python decoder is urllib3's, for replies to the app's own outbound calls (book metadata) | — | demo-hp |
|
|
| paperless-ngx | 2.20.15 (3.3.4 still py-Brotli 1.2.0, and a new main) | py-Brotli 1.1.0 | Python; decodes only replies to its own outbound calls (R-1331, decided) | — | demo-hp, Tester 1 |
|
|
| romm | 5.4.1 (newest) | Node 24.18.1 | **no Node process** (gunicorn, rq, nginx — `ps` on demo-hp) | setup gate | demo-hp (D61 = keep offered, R-1330) |
|
|
| sparkyfitness | v0.17.3 (v1.9.0 still Node 24.22.0, and a new main) | Node 24.18.0 | `tsx index.ts` (Node) | setup gate | — |
|
|
|
|
(SparkyFitness has two images; its web image is nginx and carries no Node.)
|
|
|
|
## Exposure, in plain words
|
|
|
|
A bad decoder is dangerous when the app unpacks Brotli data that an attacker chose: a request body sent with
|
|
`Content-Encoding: br`, or the reply of a server the attacker controls. In every app here the household's login (or the
|
|
family gate) stands in front of the app's own pages after setup; a Node server that unpacks request bodies, or that
|
|
fetches outside pages for its users (bookmarks, recipes, link previews — Karakeep, Tandoor, Adventurelog), is the
|
|
likelier path. No app here has a notice of its own: the watch is the only thing that sees them.
|