Individual website components can compromise the security of your entire site, and analytics platforms are no exception. With this in mind, we decided to do a quick audit of his Piwik PRO to make sure it is safe to deploy on portswigger.net.
I decided to look for client side issues like DOM XSS. The focus was on introducing a new scripting resource and the most likely vector was a DOM XSS vulnerability. The first thing I did was browse the site with DOM Invader enabled and try to inject a canary. I didn’t get any results, but this was good news. Then I changed the DOM Invader canary to a blank value. This allowed me to see all sinks being used regardless of whether a canary was present or not. This is very useful for finding things like document.write(). Indeed, there were document.write calls and various innerHTML assignments. I got the stack trace and inspected the document.write() call and noticed there was a debug flag… which led me to my next question – what does this do?
I added a flag to the URL and lo and behold the analytics debugger appeared. After testing that document.write calls are not vulnerable to XSS, I thought about the following questions: How was this debugger built? I started inspecting the debugger using devtools and immediately noticed the “ng-app” event. Jackpot, this is my old friend his AngularJS.
Once you confirm that you have an AngularJS gadget, there are two possible outcomes. You can do client-side template injection (CSTI) or bypass CSP. CSTI could not run because it requires an HTML injection vulnerability to inject script resources. If your site has HTML injection vulnerabilities, it’s important to fix them as they can be escalated to XSS using CSP bypass. I’ve done this in the past to find XSS on PayPal.
Upon further inspection, the debugger appears to be using an iframe, loading various scripting resources allowed by CSP. I went through the XSS cheat sheet to see various CSP bypasses for AngularJS. I chose the first one and typed in the console:
document.body.innerHTML=`<iframe srcdoc="<div lang=en ng-app=application ng-csp class=ng-scope>
<input autofocus ng-focus=$event.composedPath()|orderBy:'.constructor.from(,alert)'>
This is valid now – if you find something we missed, please report it to the PortSwigger and Piwik PRO bug bounty programs.
Mar 02, 2023 10:51 – Report CSP bypass to Piwik
Mar 02, 2023 11:20 – Approved by Piwik
Mar 3, 2023 13:09 – Vulnerability confirmed
03/07/2023 12:24 – CSP deployment instructions updated to fix vulnerability
Apr 28, 2023 13:00 – Blog post published
back to all articles