| **XSS-001** | DOM-based iframe src injection | `AppSession.vue:399-418` — `?path=` query param concatenated to iframe src without validation | Medium |
| **XSS-002** | DOM-based javascript: URI redirect | `Login.vue:220,384-386` — `?redirect=` flows to `window.location.href` in catch handler | Medium |
| **XSS-003** | Cross-origin message injection | `appLauncher.ts:192-284` — NIP-07 postMessage handler has **zero origin validation**, responses sent with `'*'` | **High** |
| **XSS-004** | Weak CSP (amplification) | `nginx-archipelago.conf:20` — `script-src 'self' 'unsafe-inline'` disables CSP as XSS defense | High |
The NIP-07 handler is the highest-risk finding. Any iframe (including the external HTTPS apps like botfights.net, nostrudel.ninja, etc.) can silently extract the user's Nostr public key without origin validation. The `contextBroker.ts` handler does this correctly — the `appLauncher.ts` handler does not, and sends responses with wildcard `'*'` origin.