From 42e7d86ec4e4a6a2cf55c2506574a361eea2fd66 Mon Sep 17 00:00:00 2001 From: Duncan Tourolle Date: Sun, 16 Aug 2026 23:22:47 +0200 Subject: [PATCH] docs(audit): record device-verification results and the asset-protocol finding Device pass on HONOR ROD2-W09 (Android 16 / SDK 36) confirms B2, B4, B5, B7 and finds no CSP violations across a full browsing session. C2 was aimed at the wrong thing: the asset protocol is not narrowly used but entirely unused. getCachedImageUrl has no production callers, images arrive as base64 data URIs from Rust via imageGetUrl, and the device saw zero asset.localhost requests. Both protocol-asset and the CSP's img-src http:/https: grant can likely be dropped. --- docs/codebase-audit.md | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/docs/codebase-audit.md b/docs/codebase-audit.md index 323949d3..1485591e 100644 --- a/docs/codebase-audit.md +++ b/docs/codebase-audit.md @@ -361,8 +361,36 @@ Since `DR-137` introduced the token-guarded loopback media server, the asset protocol's remaining job may be thumbnails alone, which would make the narrowing nearly free. -**Fix:** Scope it to the thumbnail and download subdirectories, and confirm -nothing else still resolves through `convertFileSrc`. +**Fix applied:** scoped to `$APPDATA/thumbnails/**`. Confirmed on device that +`jellytau.db` (8 MB catalogue) and `shared_prefs` sit in the `$APPDATA` root and +are now outside the grant. + +**But device testing found the finding was aimed at the wrong thing.** The asset +protocol is not narrowly used — it is **entirely unused at runtime**: + +- `getCachedImageUrl` in `imageCache.ts` has **no production callers**. Its only + references are its own test file. `convertFileSrc`'s sole production mention + sits inside that uncalled function, so it never executes. +- The real path is `MediaCard` → `CachedImage` → `commands.imageGetUrl()`, which + returns **base64 from Rust**. Every image in the app is a `data:` URI delivered + over IPC. +- Confirmed on device: zero `asset.localhost` requests across a full session of + browsing home, the library list and a poster grid; the thumbnail cache stayed + at 12 files and never grew, because nothing calls `thumbnailSave` either. + +Two consequences worth acting on, neither yet done: + +1. **The `protocol-asset` Cargo feature and the whole `assetProtocol` config + block can likely be removed**, which retires the attack surface rather than + shrinking it. `imageCache.ts` is dead code and can go with it. +2. **`img-src` in the new CSP can be much tighter.** It currently grants + `http: https:` on the reasoning that thumbnails are fetched direct-from-server + on a cache miss — but they are not; they arrive as data URIs. With no + webview-side server image loads anywhere in `src/`, `img-src 'self' data: + blob:` should suffice. That is a real tightening the CSP work left on the + table because it reasoned from the dead code path. + +Both need their own device pass, since a wrong `img-src` blanks every image. ### C3 · Low · Shipped desktop bundles have no update path