# CSP bypass on PortSwigger.net using Google script resources

Angular bundled in Google reCAPTCHA script, allowed by portswigger.net CSP, enables ng-on-error JS execution and nonce theft to load arbitrary scripts.

- Payout: hidden
- Severity: medium
- Program: PortSwigger Web Security
- Found by: joaxcar
- Disclosed: 2024-02-18
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/2279346
- Library page: https://bugbountylibrary.com/r/h1%3A2279346
- Tags: area:web domain:web impact:integrity kind:bounty platform:hackerone sev:medium tech:cdn technique:chained technique:source-review vuln:misconfiguration vuln:xss

**Target:** portswigger.net web pages with nonce-based CSP
**Root cause:** CSP allowlists the full https://www.google.com/recaptcha/ path which hosts an Angular bundle; Angular's ng-on-error compiles inline expressions, and the nonce can be read from the DOM and copied to an injected script.
**Steps:**
1. Load `https://www.google.com/recaptcha/about/js/main.min.js` (contains Angular) on a page whose CSP permits it
2. Inject `<img src=x ng-on-error='$event.target.ownerDocument.defaultView.alert(1)'>` to confirm Angular expression execution
3. To bypass eval/Function blocking, use ng-on-error to read `document.querySelector("[nonce]").nonce`, create a new script with that nonce pointing to attacker JS, and append to body
4. Observe the external script loads despite CSP
**How found:** Re-read PortSwigger's Piwik Angular CSP bypass research and a Twitter thread showing Google reCAPTCHA bundles Angular; noticed the CSP allowlisted the whole recaptcha path, then tested ng-on-error and nonce reuse.
**Exploitation:** Requires an HTML injection primitive on a nonce-CSP page; attacker injects Angular directives, steals the page nonce via DOM access, and loads an arbitrary external script that executes under CSP.
**Insight:** When a CSP allowlists a broad third-party path, check whether bundled frameworks (Angular) on that path can be bootstrapped via injected directives; a readable nonce in the DOM can be copied onto attacker scripts to defeat nonce-based CSP.
