# Session Cookie Leakage via Static Header Field in WebViewerFragment

Static CUSTOM_HEADERS in LinkedIn Android WebViewerFragment persists cookies across loads, leaking session cookies to attacker sites via a chained javascript: deep-link and JS bridge.

- Payout: hidden
- Severity: high
- Program: LinkedIn
- Found by: dphoeniixx
- Disclosed: 2026-03-17
- Write-up quality: 8/10
- Original: https://hackerone.com/reports/3475626
- Library page: https://bugbountylibrary.com/r/h1%3A3475626
- Tags: area:mobile domain:mobile impact:ato impact:data-leak kind:bounty platform:hackerone sev:high tech:android technique:chained technique:source-review vuln:account-takeover vuln:info-disclosure

**Target:** Android app WebViewerFragment / VerificationWebView deep-link
**Root cause:** WebViewerFragment.CUSTOM_HEADERS is a static ArrayMap never cleared between loadUrl calls, so cookies from a prior URL are re-sent to a subsequent URL lacking its own cookies.
**Steps:**
1. Open `https://www.linkedin.com/trust/verification?verificationUrl=javascript://www.linkedin.com/%0a...` deep-link; host whitelist passes but scheme is unvalidated.
2. Neutralize appended `renderContext` param by closing a string after `#`: `javascript://www.linkedin.com/%0aalert('1#')`.
3. Injected JS calls `Android.sendWebMessage(JSON.stringify({additionalWebViewUrl:'https://www.linkedin.com/http://www.linkedin.com/pulse/1'}))` to load LinkedIn and populate CUSTOM_HEADERS.
4. Second `sendWebMessage` with attacker URL plus `http://www.linkedin.com/pulse/1` suffix passes unanchored FIRST_PARTY_ARTICLE_PATTERN regex, forcing web_viewer client.
5. Attacker server receives Cookie header containing LinkedIn session tokens.
**How found:** Code review of WebViewerFragment.loadUrl revealed a static CUSTOM_HEADERS map never cleared; then traced a reachable path via the verification deep-link, noticing scheme not validated and the appended query param could be neutralized with a fragment-closing string trick, and the article regex lacked a `^` anchor.
**Exploitation:** Victim taps a crafted link opening the trust/verification deep-link with a javascript: payload; JS executes in VerificationWebView, uses the Android JS bridge to launch WebViewerFragment first on linkedin.com (caching cookies in static CUSTOM_HEADERS) then on the attacker server, which receives the leaked session cookies enabling account takeover.
**Escalation:** Chained three weaknesses: unvalidated scheme in verification deep-link, JS bridge sendWebMessage to launch WebViewer, and unanchored article regex to force the vulnerable web_viewer client.
**Insight:** Static mutable header/cookie maps in WebView wrappers leak across navigations; also check deep-link validators that whitelist host but not scheme, and regex URL checks missing `^` anchors that let you append a trusted URL suffix.
