# New XSS vector in ReaderMode with %READER-TITLE-NONCE%

Brave iOS ReaderMode failed to escape the meta author tag, letting injected script run under the relaxed nonce CSP and steal cross-origin reader pages.

- Payout: hidden
- Severity: critical
- Program: Brave Software
- Found by: nishimunea
- Disclosed: 2023-06-22
- Write-up quality: 8/10
- Original: https://hackerone.com/reports/1436142
- Library page: https://bugbountylibrary.com/r/h1%3A1436142
- Tags: area:mobile domain:browser domain:mobile impact:data-leak impact:internal-access kind:bounty platform:hackerone sev:critical tech:ios technique:incomplete-fix technique:source-review vuln:xss

**Target:** ReaderMode HTML template (localhost:6571) in brave-ios
**Root cause:** The %READER-CREDITS% placeholder is filled with the page's <meta name="author"> content without HTML escaping, and a prior commit relaxed CSP to allow scripts bearing nonce-%READER-TITLE-NONCE%.
**Steps:**
1. Serve a page containing `<meta name="author" content="Evil <script nonce=%READER-TITLE-NONCE%>alert(document.location);</script>!--">`.
2. Open the page in Brave iOS and tap the Reader Mode button.
3. ReaderModeUtils.swift substitutes %READER-TITLE-NONCE% with the real nonce, so the injected script matches the CSP and executes on http://localhost:6571/reader-mode?uri=...&uuidkey=...
4. Observe the alert dialog confirming script execution.
**How found:** Noticed a commit that relaxed ReaderMode CSP to permit nonce-%READER-TITLE-NONCE% scripts, then reviewed the Reader.html template and found %READER-CREDITS% (from meta author) is inserted unescaped while the nonce placeholder is substituted afterward.
**Exploitation:** Attacker hosts a page with a crafted author meta tag; when a victim readalizes it, the injected script runs in the localhost:6571 origin shared by all ReaderMode pages, allowing theft of other cross-origin readalized pages via iframe and, with the uuidkey in the URL, access to Brave's privileged pages.
**Escalation:** Shared localhost:6571 origin lets the XSS read other readalized cross-origin pages; the uuidkey query parameter enables reaching privileged Brave pages.
**Insight:** When a CSP nonce is a literal placeholder string substituted at render time, any unescaped template field rendered after it can smuggle a matching nonce; audit all placeholders in the same template for escaping.
