Content Security Policy

Published on Aug 07, 2015

You may be worried about hackers, but let's be real- you're probably more worried about all the errors 'Content Security Policy' puts in your console.

Get fewer errors AND be more safe by learning how to use the ember-cli-content-security-policy gem that's already included in ember-cli.


Links

Code

//package.json
devDependencies: {
  //...
  "ember-cli-content-security-policy": "0.4.0"
}
//config/environment.js
module.exports = function(environment) {
  var ENV = {
    //...
    contentSecurityPolicyHeader: 'Content-Security-Policy',
    contentSecurityPolicy: {
      'default-src': "'none'",
      'script-src': "'self' 'unsafe-inline' http://www.google-analytics.com/analytics",
      'font-src': "'self' https://fonts.gstatic.com",
      'connect-src': "'self'",
      'img-src': "'self' http://www.google-analytics.com http://trk.kissmetrics.com",
      'style-src': "'self' https://fonts.googleapis.com",
      'media-src': "'self'",
      'frame-src': "'self' http://platform.twitter.com"
    }
  }
}

Transcript

If you don’t know what Content Security Policy is but you’re using Ember cli, you’ve probably already seen its effects. This is what happens when you don’t follow the Content Security Policy. Your console fills with errors. They usually take the form of Report Only] Refused to load something, this, because it violates the following Content Security Policy directive. The reason this is happening is because you have the ember-cli-content-security addon and it was automatically installed in Ember cli, right here. In this episode, we’ll show the different ways that you can deal with this.

So the reason why it was added is because it helps mitigate the cross site scripting and reduce packet sniffing attacks. The way it does this basically is only letting your site load things from the sites that you’ve whitelisted. So if an attacker wants to take advantage of your web app, it first has to infiltrate something that you’ve taken code from on purpose. It makes it much harder to inject stuff. At least that’s the impression I get from reading these docs. I’m not an expert in security.

So how it does this is it uses the HTTP header, Content-Security-Policy. It’s not in all browsers yet, but the ones that don’t have it will just drop it and won’t follow it. So those browsers will be less safe, but they won’t stop working.

So back to our screen full of red. How do we get these to go away? There’s two options. The first is you just remove the content-security-policy, and then it won’t give you any more warnings. But your website will not be as secure as if you had hewed to the content security policy. So let’s add that back in and get to work.

On the readme for the addon, we can find the default contentSecurityPolicy. We’ll take that, we’ll copy it, and then we’ll go to config/environment.js and paste it in there. So this is just what we had before, what it was doing by default, but now we can start editing it. We’ll start at the top. We’ll take this first one, the style sheet, https://fonts.googleapis.com/, we’ll copy it, and then we’ll go to style source... most of this is named pretty well. We can paste it in. But we don’t. We’ll go ahead and make it more general. Anything from https://fonts.googleapis.com/ can insert in styles. So we go back, and when we reload we notice that it’s still giving the warning. For some reason I have to ‘Empty Cache and Hard Reload` to get these to change.

Alright, and then we’ll go through and do the rest of them, and we’ll skip ahead to a world we’re we’ve already done all of it. So we’ve got some in scripts, we’ve got some in fonts, images, styles, and a new one called frame that wasn’t included in our original list but was needed nonetheless.

But we’re not completely done. As you can see, there’s still some that says ‘Refused to execute inline script’. How do we fix that? Well, we have two options for this. The first is to add to our script source unsafe-inline. As you might guess from the name, it’s unsafe and not recommended. But it does get rid of those warnings. Another option is to use a nonce. So here we’ll put nonce- and then something else, so like helloworld. And notice these are within quotes, just like safe, none and unsafe-inline were. Then we can go to wherever our problems are and then we take our scripts, we do nonce=helloworld on both of these. And then when we reload this, we should have only two. Right. There are two and there were four before, so these two that we added nonces to are working.

Of course this isn’t a whole lot safer than unsafe-inline because anyone can just say like oh, I want to hack this place, I’m just going to add nonce=helloworld. So what you need to do is to make it random. Unfortunately that’s not possible in this app since it’s being taken from Rails, and it’s difficult for Ember to communicate back to Rails the nonce. So for now, we’ll go back to unsafe-inline. And this is great. We’ve gotten rid of all our warnings.

However, it still isn’t going to protect us because we haven’t turned it on yet. So let’s turn that on. We will need to use the contentSecurityPolicyHeader, and by default it’s Report-Only. We’ll change it to Content-Security-Policy. So it’ll make it block any action that conflicts. So now it should be on. Let’s go ahead and test it by removing our connection with Amazon, so it’s no longer allowed to get images from Amazon. And what that should do is make it so this image no longer appears. And this failure is a success.

So in this episode, we learned about the Content Security Policy. It’s the reason why sometimes you’ll get a lot of errors in your console, and it’s done via this addon, which is added automatically to Ember cli projects. You can remove the addon, or you can work on making your Content Security Policy something that’s both secure and allows in everything you need. You do that by going one by one through the errors it gives you, and then when you’re ready to turn it on for real, you set this option to Content-Security-Policy. So good luck out there, be safe, and I’ll see you next week.

Subscribe to our mailing list