I recently had some great fun using CSP in a way that I've been really excited to talk about. We are starting to utilise the full power of CSP reports to find a way to hunt down malware infected endpoints on a corporate network!
Building on previous work
I have spoken in the past about using CSP to combat ad-injectors where nasty browser extensions were doing naughty things and inserting adverts into pages you visited. CSP of course has the ability to stop these because they're loading content into the DOM that isn't whitelisted in the CSP so the browser blocks it. Blocking the nasty things is great and of course you can enable reporting with https://report-uri.com to be notified when these things happen to get real-time feedback. In most cases though all you find out is that one of your visitors has a malicious browser extension installed and there's not really much you can do about that. Some random person on the Internet has come by your site and you have no way to notify them of their infection so the reports are largely just noise and Report URI actually has filters to remove them if you wish. Things can be a little different though.
Monitoring internal websites
That scenario changes somewhat when you aren't moitoring CSP reports on a public website that anyone can visit but an internal website, like a support ticket system or an intranet site, and the only people that can visit it are employees on your internal network. I recently came across this scenario with a customer of Report URI who got in touch with me directly and provided a few sample reports that they just couldn't figure out, let's call them ACME Corp. I will show one of the reports here but most values will be altered/redacted to shield the identity of those involved.
"original-policy": "*policy here*; report-uri https://acme-corp.report-uri.com/r/d/csp/enforce",
A simple idea
I bounced some ideas around about how we could try to tackle this and came up with an idea that might just do it. It would only work because of the fairly unique scenario we found ourselves in and it wasn't exactly clean, but it seemed like the only way. The JSON payload was all that we had to work with from the client so we had to get something into the payload to uniquely identify the client that we could also correlate on their side. The
document-uri field contains the address the browser was visiting and it also includes any query string present in the URL. If the site could place a random token into the query string it would be present in the CSP report
document-uri field and in the server logs for the site with the associated interal IP of the endpoint. The only easy option that ACME Corp had to do this was after the user had logged in. When they authenticated and were redirected to the homepage of the intranet site it was pretty easy for them to just add a random GET parameter to the URL and this would be reflected into the CSP report when it was fired. All they would then have to do is wait for the infected endpoint to trigger a report and grep the server logs for the unique ID to find the offending endpoint. Sadly, before we got chance to deploy our magnificent solution another member of ACME Corp had wondered how these endpoints had been infected and based on some of the pages that were firing reports they took a guess as to what department they may have been in. He checked around and some devices had local admin rights for a legacy app and, unsurprisingly, he'd found the offending endpoits. Of course that was great news but I'd really wanted to see how our CSP detection strategy would have worked out so I did a PoC myself and I'm pretty happy to say that it did indeed work.
The CSP report:
The server log:
192.168.1.29 - - [14/Dec/2017:17:57:23 +0000] "GET /csp-test/?v=abc123 HTTP/2.0" 200
Et voila! I think this is a really awesome way to take a tool like CSP and use it creatively to solve new problems. Yes it was a little clunky and requires favourable circumstances but I genuinely enjoyed the challenge of trying to take the tools at our disposal and craft them into something useful. Who knows, perhaps this could help someone else one day but I thought it'd be an interesting story to share nonetheless.