jahed.dev

FrontierNav Security - CSP and SRI

I can't remember how I started going down this route, but I do know that as someone with multiple websites, I should be doing the most to ensure nothing malicious is being loaded onto my viewer's computer.

Actually, I do remember. I was looking into how FrontierNav can introduce an iframe-based, postMessage API to allow third-party integrations -- an exciting topic for another time. Loading iframes from other places is of course open to abuse, so I looked into securing it.

A Quick Rundown

Content Security Policy (CSP)

CSP is a way for websites to let the viewer's browser know what resources are okay to load and execute. So I can say things like "don't load Iframes, even if I tell you to" in case one of the scripts I run gets hi-jacked.

Of course, there are limitations to this approach -- it's useless if the attacker has access to the server which generates the CSP -- but it's another barrier to go through.

Subresource Integrity (SRI)

SRI is another feature browsers support which essentially tells the browser "make sure the script you load from this URL is this one". The way it does this is by comparing hashes. I take the file, run it through SHA-512 and include it in the <script> tag. Then when the browser downloads the script, it also runs it through SHA-512 and compares it to my result. If they don't match, it doesn't run the script and throws it away.

So if anyone tries to modify just the script either on the server or the CDN, they'll need to also modify the hash in the HTML. Again, limited, but another barrier.

We'll do it live!

Both CSP and SRI is based on restricting the network requests on the site. It's pretty much impossible to properly test it outside of production. So I did it live.

SRI was simple. Someone wrote a Webpack plugin for it. It doesn't cover dynamically loaded stylesheets yet but it's good enough.

CSP was more of a pain. I'm using Firebase which is a bit of a black box, I don't really know what it's doing and why, which is one of its selling points. Authentication and real-time updates is complicated, so until I get the time to roll my own, I'll have to accept it.

My first approach was a bit naive. I loaded up FrontierNav, did a few things, looked at the network logs, and added the domains to the whitelist. Deployed and stared at my error logs.

Turns out Firebase loads different URLs in different contexts, no idea why. For example, it loads an Iframe in Firefox, but I didn't see it in Chrome.

Anyway, CSP has a useful feature which tells browsers to send over the reason why something was blocked. With this, I don't need to try everything myself, I can let the blocklists come through and whitelist the ones I'm okay with.

That took a while since FrontierNav isn't exactly high in traffic. But now, I know exactly which domains are running on the website. Sadly, Google is one of them. Wonderful.

Thanks for reading.