Tracked follow-up from the Home v2 grant-hardening work (PR #277). Not a cross-app escalation — that is closed. This is the accepted within-principal residual.
What
On Android, all QDN apps render through one shared per-node proxy origin, and the bridge token is a bearer value carried in the app iframe's URL. Because of that, an app can navigate its own iframe to non-APP /arbitrary/... HTML on the same origin, read the token from its own location.href, and drive the bridge under its own already-granted identity.
What this is NOT
It does not let one app obtain a different app's grant or token. Cross-app theft is prevented by: a unique per-tab bridge token, only one app iframe existing at a time (keyed stage), and the exact shell-authorized-URL token gate. So the capability an app gains is CSP-escape / running non-published attacker code under its own principal — not becoming another principal.
Why it isn't fixable by gating
Six adversarial review rounds confirmed the root is architectural: shared single origin + URL bearer token = no per-document principal integrity. Every incremental gate leaked a same-class variant until the exact-URL gate closed cross-app theft; this residual remains.
Real fixes (either, both large)
- Per-app origins on Android — the clean isolation desktop gets via separate WebContentsViews — but this regresses QDN apps' own local storage between visits (the reason the shared origin exists). Would need a storage-migration/partition strategy.
- Non-URL token handshake — deliver the bridge token out-of-band (e.g. parent→frame postMessage capability the served document can't read from its URL), so a document loaded on the origin can't self-authenticate as the app.
Acceptance
Owner-accepted for the current release (2026-08-13): desktop is fully isolated; Android cross-app theft is closed; this within-principal residual is documented in docs/HOME_V2_BRIDGE_COMPATIBILITY.md and deferred to this issue. Revisit before broadening Android's signing/write surface beyond CHAT.
Tracked follow-up from the Home v2 grant-hardening work (PR #277). Not a cross-app escalation — that is closed. This is the accepted within-principal residual.
What
On Android, all QDN apps render through one shared per-node proxy origin, and the bridge token is a bearer value carried in the app iframe's URL. Because of that, an app can navigate its own iframe to non-APP
/arbitrary/...HTML on the same origin, read the token from its ownlocation.href, and drive the bridge under its own already-granted identity.What this is NOT
It does not let one app obtain a different app's grant or token. Cross-app theft is prevented by: a unique per-tab bridge token, only one app iframe existing at a time (keyed stage), and the exact shell-authorized-URL token gate. So the capability an app gains is CSP-escape / running non-published attacker code under its own principal — not becoming another principal.
Why it isn't fixable by gating
Six adversarial review rounds confirmed the root is architectural: shared single origin + URL bearer token = no per-document principal integrity. Every incremental gate leaked a same-class variant until the exact-URL gate closed cross-app theft; this residual remains.
Real fixes (either, both large)
Acceptance
Owner-accepted for the current release (2026-08-13): desktop is fully isolated; Android cross-app theft is closed; this within-principal residual is documented in
docs/HOME_V2_BRIDGE_COMPATIBILITY.mdand deferred to this issue. Revisit before broadening Android's signing/write surface beyond CHAT.