Trust is the fundamental currency of the internet. You trust your service provider that they’ll continue to maintain your internet access. Your developers trust your architecture provider when they say that your servers will stay up. Customers trust that you’re safely securing your data. They also trust that when they visit your website, what they’re seeing is what you want them to see.
A common attack vector against public websites is injecting content which claims to be from that website. In reality, it’s content that’s hosted elsewhere. Once it’s loaded and executed on a customer’s computer, it likely takes advantage of them in some way. Those attackers might use XSS attacks, injecting malicious iFrames or Clickjacking.
Obviously, these kinds of attacks erode your customers’ trust in your organization. They often confuse them, which leads to abandoning a shopping cart or an uptick in support tickets. The monetary costs for these attacks have a real impact on your business.
How does a Content Security Policy help?
Thankfully, there’s a tool your team can use to prevent these kinds of attacks. Known as a Content Security Policy, it’s a mechanism built directly into web browsers which limits what the browser will do on your website.
When your website includes a Content Security Policy, the browser inspects every item that the website’s HTML requests. If the origin of the item isn’t allowed by the content security policy, it’s not downloaded. If it’s a script, and it comes from an unpermitted source, it’s not executed. You define a list of rules, and anything which doesn’t match that list of rules is eliminated before it reaches a user’s computer.
Obviously, this kind of protection is a powerful deterrent against website-damaging attacks. Instead of being annoyed by popups or exposing their credentials to an attacker, your customers get the experience you’ve intended.
Using a CSP to prevent packet sniffing
One uncommon benefit of a content security policy is that you can force the browser to encrypt communications with your server. While you might provide an HTTPS endpoint for your users, some browsers won’t connect to HTTPS by default. Others will still connect to HTTP, even if HTTPS is the default. Using the content security policy, your team can define the acceptable ways to connect your server. If you limit the acceptable communications channels to encrypted ones, you can ensure that your communication with users is secure. Secure communications are another important piece of making sure that your customers can trust your website. What’s more, they’re an important piece that help you ensure you can trust your customers.
Enforcing encryption standards using CSP doesn’t just extend to communication, either. Using standard CSP directives, you can ensure that the browser will also encrypt things like cookies when they’re stored on a user’s machine. Savvy attackers who gain access to a user’s computer will commonly examine stored cookies to look for things like stored passwords, user IDs, or session identifiers. Encrypting your cookies prevents these users from being able to shortcut common ATO attacks.
How can I set up a Content Security Policy?
Setting a Content Security Policy for your webserver is shockingly simple. It’s easy to do in ASP.NET MVC, Ruby on Rails, or Django. If you program in a different language or framework, a short google will likely lead to a quick tutorial about how to set it up in your workflow. If there isn’t a simple answer in your application programming language, it’s pretty simple to set up in Apache or Nginx, too.
It’s likely that the real challenge of setting a Content Security Policy won’t actually be technical. Technically, it amounts to a few lines of code.
Instead, the real challenge of setting a Content Security Policy is likely to be in cataloging all of the content your website delivers. Modern websites include a variety of scripts and stylesheets. Often, these come from a variety of different sources, many of which might not be your website. For instance, most websites will serve things like images, scripts and stylesheets from a content delivery network. By default, a Content Security Policy is going to break all of those things. A poorly-configured Content Security Policy is a quick path to a website that loads as nothing more than a blank white page and a hundred browser console errors.
If you have a website that’s been online for a while, it’s possible nobody on your team knows all the sources that website uses. Setting up a working Content Security Policy might be a process of trial and error for your developers. The good news is at the end, you’ll have a more secure website and a better understanding of your web presence.
How can I make sure my CSP doesn’t break my site?
Like we noted above, messing up your Content Security Policy has harsh side effects. Your website breaks completely. Your users are left out in the cold. These negative side effects scare away some companies. They ship one bad Content Security Policy, the website breaks, and they throw the baby out with the bathwater. Obviously, this isn’t a wise tactic. Luckily, browsers have another built-in tool to make sure that your website doesn’t break when you enable a CSP. It’s the Report Only directive.
The Report Only directive does exactly what it says. Instead of stopping parts of your website from working, the browser logs errors to the browser console. By adding a Report Only directive, your team can pick through each violation of the Content Security Policy and fix them one by one. If you’re not a senior leader of your organization, this directive can be a real life saver. Instead of deploying an update that knocks your website offline, you can ensure that there are no problems before you turn on your CSP.
How can I make sure my CSP is actually useful?
It’s important to make sure that when your team adds a CSP to your website, you’re doing useful work. To be useful, you need to both set up your CSP properly and maintain it. Once your CSP is in place, you need to monitor and maintain it whenever your website changes — be it new assets, new tracking tools, new ad platforms, and so on. It’s crucial to implement a solution to ensure that your CSP remains up-to-date and enables you to add or remove assets as your website changes.
The scope of your CSP is important. Just like when you configure a firewall, you don’t want to make it too permissive. One very common mistake is to allow “unsafe inline” scripts to execute on your page. As that link shows, this is the type of mistake that even big companies like Blogger and Google make. Setting an unsafe-inline directive means that all that white-listing you did for scripting is pointless.
If you’re just getting started setting a content security policy on your website, I highly recommend giving that link a good read-through. There are a number of recommendations for how to effectively configure your CSP. What’s more, there are useful examples of ways that you can test to make sure your CSP is working as directed. By testing your CSP in action, you can be confident that it’s protecting your customers when you turn it on.
A CSP is a gatekeeper for your website
That’s the simplest way to describe a content security policy. It acts like a gatekeeper for your website. A good CSP limits where data on your site can come from, and what scripts can be executed. Configuring and maintaining a good content security can be a bit of work, especially if your site has been online for a while or changes with any frequency. That time pays for itself though, whether via manual effort or good tooling, through the trust of your customers and time saved troubleshooting website security issues. If your team has been considering adding a CSP to your site, they’re a powerful tool for protecting against XSS and click-jacking, adding an additional layer of defense and improving your overall site security posture.
This post was written by Eric Boersma. Eric is a software developer and development manager who’s done everything from IT security in pharmaceuticals to writing intelligence software for the US government to building international development teams for non-profits. He loves to talk about the things he’s learned along the way, and he enjoys listening to and learning from others as well.