Content Security Policy with Next.js: Leveling Up your Website's Security

Rate this content
Bookmark
Project website

In this talk, we'll explore the powerful security feature of Content Security Policy (CSP) and how it can be implemented in Next.js to bolster your website's defenses against common web attacks like Cross-Site Scripting (XSS) and data injection. We'll cover the basics of CSP, its benefits, and best practices for implementing it in Next.js. 


Additionally, we'll share some tools to evaluate and test your policy. By the end of this talk, you'll have a solid understanding of how to level up your website's security with CSP and protect your users from the ever-present threats of the modern web.

9 min
15 Nov, 2023

Video Summary and Transcription

Lucas Estevão, a Principal UI Engineer and Technical Manager at Avenue Code, discusses how to implement Content Security Policy (CSP) with Next.js to enhance website security. He explains that CSP is a security layer that protects against cross-site scripting and data injection attacks by restricting browser functionality. The talk covers adding CSP to an XJS application using meta tags or headers, and demonstrates the use of the 'nonce' attribute for allowing inline scripts securely. Estevão also highlights the importance of using content security reports to identify and improve application security.

Available in Español

1. Introduction to Content Security Policy

Short description:

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

Short description:

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

Short description:

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

Short description:

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.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

React Summit 2022React Summit 2022
20 min
Routing in React 18 and Beyond
Top Content
Concurrent React and Server Components are changing the way we think about routing, rendering, and fetching in web applications. Next.js recently shared part of its vision to help developers adopt these new React features and take advantage of the benefits they unlock.In this talk, we’ll explore the past, present and future of routing in front-end applications and discuss how new features in React and Next.js can help us architect more performant and feature-rich applications.
React Summit 2023React Summit 2023
23 min
React Concurrency, Explained
Top Content
React 18! Concurrent features! You might’ve already tried the new APIs like useTransition, or you might’ve just heard of them. But do you know how React 18 achieves the performance wins it brings with itself? In this talk, let’s peek under the hood of React 18’s performance features: - How React 18 lowers the time your page stays frozen (aka TBT) - What exactly happens in the main thread when you run useTransition() - What’s the catch with the improvements (there’s no free cake!), and why Vue.js and Preact straight refused to ship anything similar
React Advanced Conference 2022React Advanced Conference 2022
29 min
Understanding React’s Fiber Architecture
Top Content
We've heard a lot about React's Fiber Architecture, but it feels like few of us understand it in depth (or have the time to). In this talk, Tejas will go over his best attempt at understanding Fiber (reviewed by other experts), and present it in an 'explain-like-I'm-five years old' way.
Node Congress 2022Node Congress 2022
26 min
It's a Jungle Out There: What's Really Going on Inside Your Node_Modules Folder
Top Content
Do you know what’s really going on in your node_modules folder? Software supply chain attacks have exploded over the past 12 months and they’re only accelerating in 2022 and beyond. We’ll dive into examples of recent supply chain attacks and what concrete steps you can take to protect your team from this emerging threat.
You can check the slides for Feross' talk here.
React Summit 2022React Summit 2022
27 min
Inside Fiber: the in-depth overview you wanted a TLDR for
I want to provide an in-depth overview of the important concepts behind reconciliation. We'll then explore how React uses the algorithm and go through a few magic words we hear a lot, like coroutines, continuations, fibers, generators, algebraic effects and see how they all relate to React.js.
React Summit 2023React Summit 2023
26 min
Server Components: The Epic Tale of Rendering UX
Server components, introduced in React v18 end these shortcomings, enabling rendering React components fully on the server, into an intermediate abstraction format without needing to add to the JavaScript bundle. This talk aims to cover the following points:1. A fun story of how we needed CSR and how SSR started to take its place2. What are server components and what benefits did they bring like 0 javascript bundle size3. Demo of a simple app using client-side rendering, SSR, and server components and analyzing the performance gains and understanding when to use what4. My take on how rendering UI will change with this approach

Workshops on related topic

React Advanced Conference 2021React Advanced Conference 2021
132 min
Concurrent Rendering Adventures in React 18
Top Content
Featured WorkshopFree
With the release of React 18 we finally get the long awaited concurrent rendering. But how is that going to affect your application? What are the benefits of concurrent rendering in React? What do you need to do to switch to concurrent rendering when you upgrade to React 18? And what if you don’t want or can’t use concurrent rendering yet?

There are some behavior changes you need to be aware of! In this workshop we will cover all of those subjects and more.

Join me with your laptop in this interactive workshop. You will see how easy it is to switch to concurrent rendering in your React application. You will learn all about concurrent rendering, SuspenseList, the startTransition API and more.
React Summit 2020React Summit 2020
125 min
Getting Started with Suspense and Concurrent Rendering in React
Featured Workshop
React keeps on evolving and making hard things easier for the average developer.
One case, where React was not particularly hard but very repetitive, is working with AJAX request. There is always the trinity of loading, success and possible error states that had to be handled each time. But no more as the `<Suspense />` component makes life much easier.
Another case is performance of larger and complex applications. Usually React is fast enough but with a large application rendering components can conflict with user interactions. Concurrent rendering will, mostly automatically, take care of this.
You will learn all about using <Suspense />, showing loading indicators and handling errors. You will see how easy it is to get started with concurrent rendering. You will make suspense even more capable combining it with concurrent rendering, the `useTransition()` hook and the <SuspenseList /> component.
React Summit 2022React Summit 2022
173 min
Build a Headless WordPress App with Next.js and WPGraphQL
Top Content
WorkshopFree
In this workshop, you’ll learn how to build a Next.js app that uses Apollo Client to fetch data from a headless WordPress backend and use it to render the pages of your app. You’ll learn when you should consider a headless WordPress architecture, how to turn a WordPress backend into a GraphQL server, how to compose queries using the GraphiQL IDE, how to colocate GraphQL fragments with your components, and more.
React Day Berlin 2022React Day Berlin 2022
53 min
Next.js 13: Data Fetching Strategies
Top Content
WorkshopFree
- Introduction- Prerequisites for the workshop- Fetching strategies: fundamentals- Fetching strategies – hands-on: fetch API, cache (static VS dynamic), revalidate, suspense (parallel data fetching)- Test your build and serve it on Vercel- Future: Server components VS Client components- Workshop easter egg (unrelated to the topic, calling out accessibility)- Wrapping up
React Summit 2023React Summit 2023
56 min
0 to Auth in an hour with ReactJS
WorkshopFree
Passwordless authentication may seem complex, but it is simple to add it to any app using the right tool. There are multiple alternatives that are much better than passwords to identify and authenticate your users - including SSO, SAML, OAuth, Magic Links, One-Time Passwords, and Authenticator Apps.
While addressing security aspects and avoiding common pitfalls, we will enhance a full-stack JS application (Node.js backend + React frontend) to authenticate users with OAuth (social login) and One Time Passwords (email), including:- User authentication - Managing user interactions, returning session / refresh JWTs- Session management and validation - Storing the session securely for subsequent client requests, validating / refreshing sessions- Basic Authorization - extracting and validating claims from the session token JWT and handling authorization in backend flows
At the end of the workshop, we will also touch other approaches of authentication implementation with Descope - using frontend or backend SDKs.
React Summit 2023React Summit 2023
139 min
Create a Visually Editable Next.js Website Using React Bricks, With Blog and E-commerce
WorkshopFree
- React Bricks: why we built it, what it is and how it works- Create a free account- Create a new project with Next.js and Tailwind- Explore the directory structure- Anatomy of a Brick- Create a new Brick (Text-Image)- Add a title and description with RichText visual editing- Add an Image with visual editing- Add Sidebar controls to edit props (padding and image side)- Nesting Bricks using the Repeater component- Create an Image gallery brick- Publish on Netlify or Vercel- Page Types and Custom fields- Access Page meta values- Internationalization- How to reuse content across pages: Stories and Embeds- How to create an E-commerce with Products’ data from an external database and landing pages created visually in React Bricks- Advanced enterprise features: flexible permissions, locked structure, custom visual components