1. Introduction to Content Security Policy
I'm Lucas Estevão, Principal UI Engineer and Technical Manager at Avenue Code, a consultancy through which I've been helping companies like Toys R Us, Wal-Mart and even the iconic Apple to build better software. I am really excited to talk to you about Content Security Policy with Next.js and how you can level up your website security. A CSP or a content security policy is a security layer that helps to shield applications from like cross-type scripting, XSS or data injection attacks, and it does it by restricting the browser functionality.
Hi everyone. Thanks for having me at the React Summit US 2023. I'm Lucas Estevão, Principal UI Engineer and Technical Manager at Avenue Code, a consultancy through which I've been helping companies like Toys R Us, Wal-Mart and even the iconic Apple to build better software. I also host a podcast about career in tech for Portuguese speakers, so if you're curious, check it out on the major streaming platforms. You just need to search for Códigos de Carreira.
I am really excited to talk to you about Content Security Policy with Next.js and how you can level up your website security. I want to start answering why should I care about a content security policy? And to keep it short, your browser is not 100% safe. Neither is React or Next.js or whatever framework that you might be using. Although browsers do have built-in security features like single origin policy and course, we can't take it for granted. The libraries and frameworks like React or Next.js, again, they do a pretty decent job sanitizing the code and providing with features to close the security gaps, but that's not enough. If a code like this is injected in your website, your browser or React default features can't prevent this from being executed. That's when a CSP comes handy.
A CSP or a content security policy is a security layer that helps to shield applications from like cross-type scripting, XSS or data injection attacks, and it does it by restricting the browser functionality. A CSP is composed by a list of policy directives. The browser will be limited to allow only what the policy defines. Here are examples of policy directives, where I'm defining that the default sources of content should come from my domain and I'm adding an exception for fonts because I want to allow Google web fonts to be downloaded. Now let's see how we can implement that in an XJS app. Let's go hands-on now.
2. Adding Content Security Policy
This is an XJS application. We want to add the CSP to the page. The easiest way is by adding it to the head tag using a meta tag. Let's try adding headers instead. We'll add a simple content security policy to see it working on the headers. Next, we'll try using a middleware to add a content security policy. Create a new file called middleware.ts on the root of our app and refer to the documentation for more details.
Okay, so this is an XJS application, just a template I created using NPX. The first thing we want to try to do is to add the CSP to the page. And the easiest way to do it is adding this on the head tag using a meta tag.
So let's go to the application and see that the image is not being displayed here. And the image is not being displayed because it comes from a different domain. It comes from React Summit. And my directive it's enforcing that the content should come by default from my own domain. The image shouldn't show up, but let's remove this from here. That's not the best way to add a content security policy.
Let's try doing it adding headers. So if you go to the documentation, you see how to add headers to your Next.js application, and you see a bunch of options to add different headers, including the content security policy. So I prepared something here. I picked a few of the security headers. I'm gonna add them to our Next.js config app. And I'm going to add the headers as well. And again, this is all available on the docs. I'm gonna save this, and let's go to step number two.
What we wanna do here is just to add a simple content security policy to actually see it working on the headers. So I'm gonna do this and add the content security policy to my header. And I wanna see this happening in action. It's reloading. I'm gonna reload this page. Just to make sure, I'm gonna go to the network tab. Let's check it out. Open this, you can see the content security policy is there exactly the way we set it. The image is still not showing up. Let's go to step number three and actually try to use it to add a content security policy using a middleware. And for that, we're gonna create a new file on the root of our app. So new file, actually not here, but on the root, new file middleware.ts, let me move this to here. And if you go to the documentation again, you can see everything about how work with the middlewares.
3. Adding Content Security Policy - Part 2
And I'm gonna get this example that is already adding denounce. And there will be cases when you need inline scripts. And for those scenarios, announce will allow your scripts to execute without losing the security of your CSV. And announce is just a string, a hash created for one time use. So let's see it in action.
And I'm gonna get this example that is already adding denounce. And there will be cases when you need inline scripts. And for those scenarios, announce will allow your scripts to execute without losing the security of your CSV. And announce is just a string, a hash created for one time use. So let's see it in action.
I'm gonna copy these based on the middleware. I actually prepared a custom content security policy here, simpler than this one. So I'm gonna replace that. And another thing that I wanna do is to add some rules conditionally. So I'm gonna add this little code here, to check what's my environment. If it's not production, I'll assume it's dev. And if it's dev, I can lose my CSP. If it's production, I can make it more strict. So I saved.
Let's go to step number four, and do a little cleanup. Let's go to next config, and actually remove the content security policy from there. I'm gonna save this. It should look like this, exactly the way it is in our middleware. And let's see how the application is working now. Pretty much the same thing. Let's reload to make sure. Let's check if the content security policy, it's showing up in the headers. Oh, it's loading. Here we go, content security policy. Everything that we added, including the now's. Let's check for the xnow's header. It's also here, because we're adding the header in this line. Now we need to validate our content security policy, and for that we can use pretty much two websites. One, you can just copy your content security policy and paste into Google's one. I'm gonna remove this little condition, otherwise it's not gonna work, and check.
4. Using Content Security Reports
You can use a content security report to identify issues in your application and improve its security. By adding your domain, you can generate a report that provides insights on what needs improvement or correction. Additionally, you can modify your content security policy to allow specific resources, such as images, without breaking your app. Take advantage of this report to enhance the security of your web application.
It's gonna give you pretty much a report of everything that we need to improve or make better or maybe something's missing or it's wrong. You can add your domain here if you want. Then you also has Mozilla, so let's check apple.com for instance. Here we go, you have your content security report with a bunch of other information about the security of your website.
But one thing that we should do here that I forgot, it's to actually add React Summit domain to my image directive. So this way, I could actually see the image being loaded. So let's check our app one more time. Let's wait for the hot reload and here we go. Here's the image because now my content security policy allows it.
Now, a bonus tip, you don't need to break your app. You can simply use a content security report to identify the issues on your application. And once you know what's going on, you can then enforce and prevent your app from breaking while you add a new security layer to level up the security of your web application. Thank you. I hope you find this content useful and you can improve the security of your apps.
Comments