Stop the cross-site script kiddies from pwning you.
How to keep your codebase safe against stray "<script>alert("Hello")</script>" snippets.
In this essay, I will talk about Cross-Site Scripting (XSS), the bane of my existence in 2021.
Your users are mad at you now because it was your site that made them buy a JPEG of a monkey for millions of dollars. The world is burning, you have to take your site down, your reputation is in absolute shambles, you’re getting fired, your RSUs are worth 10% of what they were worth yesterday.
You could have avoided this, it didn’t have to be this way. But how?
Let me guide you through the amazing world of XSS controls.
The first thing you want to do is make sure you use a framework with safe defaults. As we all know, developers are lazy plagiarists. If you leave the average developer alone for a few hours with a Jira ticket to work on, they will have cargo-culted 500 lines of code 99% of the time. You want your developers to cargo-cult safe code, not unsafe code. The easiest thing to do here is to just use React. Just do it, don’t be weird. No Vue, no Angular, just use React like a normal person.
The second thing you want to make sure is that developers know that using any method that starts with “dangerously” is not a good idea. This might seem obvious on the outset, but to the unique species of a developer trying to get some code to work before a deadline, it’s not. You can go full dictator here and ask that you review every change that calls dangerous methods like “dangerouslySetInnerHTML”. The only thing that can make developers stop using dangerous methods is another developer or a CI build telling them not to use it. Just make sure that you mark any dangerous patterns you find as dangerous. It’s probably also worth looking over any existing dangerous patterns in the codebase (so that you can partner with a friend to get that sweet bug bounty money, just kidding. Unless…?? Nah, just kidding).
The third and final thing you want to do is to accept that all of the above will fail. Someone will find some weird-ass edge case where something got through. You CANNOT stop this if your codebase is larger than a few hundred files. So, you need a fallback. The fallback you need is a secure Content Security Policy (CSP). Content Security Policies tell the browser what code is ok to execute and what isn’t. Try to be as strict here as possible, this will save you on multiple occasions. And remember, if you allow `unsafe-inline` in your CSP, you might as well just not have CSP.
This should protect you against 99% of XSS attacks, for the rest, reach out to me on Twitter so that I can ghost you after spending 5 hours on the problem and still not solving it.
Thanks for reading newsletter.param.codes! Subscribe for free to receive new posts and support my work.