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

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.

Rate this content
Bookmark
Project website
Video Summary and Transcription
The video discusses the importance of implementing a Content Security Policy (CSP) in Next.js applications to enhance website security. CSP acts as a security layer to protect against cross-site scripting (XSS) and data injection attacks by restricting browser functionality. Adding a CSP can be done using HTTP headers or a meta tag in the head section. The talk also highlights using middleware for more specific conditions. The concept of 'nonce' is explained as a unique token that allows specific inline scripts to run safely without compromising the security policy. Tools like Google's CSP Evaluator and Mozilla Observatory can be used to validate and improve CSPs. The talk emphasizes the flexibility of CSP, allowing developers to tailor it to different environments, such as having a more relaxed policy during development and a stricter one in production. Additionally, CSP reports can be generated to identify potential issues and improve application security. The video is a valuable resource for developers interested in topics like nextjs csp, nextjs content security policy, csp nextjs, next js csp, and content security policy nextjs.

FAQ

Yes, a Content Security Policy can be tailored to be environment-specific. For instance, in a development environment, a CSP can be more relaxed to facilitate testing, while in production, it can be made stricter to provide enhanced security against attacks.

Examples of policy directives in a CSP include specifying default sources of content, such as limiting sources to your own domain, and adding exceptions, like allowing Google web fonts to be downloaded. These directives help control where content can be loaded from, enhancing security.

To validate a CSP for a Next.js application, you can use tools like Google's CSP Evaluator or Mozilla Observatory. These tools analyze the CSP and provide reports on potential improvements or issues, helping ensure the policy effectively secures the application.

In a Next.js app, a CSP prevents unauthorized content by enforcing rules that restrict external content sources. For example, if a CSP only allows content from the app's own domain, any attempt to load an image from a different domain would be blocked unless explicitly allowed in the CSP.

A Content Security Policy (CSP) is a security layer that helps shield applications from threats like cross-site scripting (XSS) and data injection attacks by restricting browser functionality. It defines a list of policy directives that limit what the browser is allowed to execute, enhancing the security of web applications.

You can find examples and detailed documentation on implementing Content Security Policies in Next.js on the official Next.js documentation website. Additionally, sample applications implementing CSP can often be found on repositories like GitHub.

A 'nonce' is a one-time token used in a CSP to allow specific inline scripts or styles to execute while maintaining overall policy compliance. This is useful when you need to run inline scripts safely, as each script must include the unique nonce value to execute.

To implement a Content Security Policy in a Next.js application, you can add a CSP directly in the HTML using a meta tag in the head section or more securely through HTTP headers. The Next.js documentation provides detailed options on how to add different headers, including CSP, to your application configuration.

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.

Lucas Estevão
Lucas Estevão
9 min
15 Nov, 2023

Comments

Sign in or register to post your comment.

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

Routing in React 18 and Beyond
React Summit 2022React Summit 2022
20 min
Routing in React 18 and Beyond
Top Content
Routing in React 18 brings a native app-like user experience and allows applications to transition between different environments. React Router and Next.js have different approaches to routing, with React Router using component-based routing and Next.js using file system-based routing. React server components provide the primitives to address the disadvantages of multipage applications while maintaining the same user experience. Improving navigation and routing in React involves including loading UI, pre-rendering parts of the screen, and using server components for more performant experiences. Next.js and Remix are moving towards a converging solution by combining component-based routing with file system routing.
React Concurrency, Explained
React Summit 2023React Summit 2023
23 min
React Concurrency, Explained
Top Content
Watch video: React Concurrency, Explained
React 18's concurrent rendering, specifically the useTransition hook, optimizes app performance by allowing non-urgent updates to be processed without freezing the UI. However, there are drawbacks such as longer processing time for non-urgent updates and increased CPU usage. The useTransition hook works similarly to throttling or bouncing, making it useful for addressing performance issues caused by multiple small components. Libraries like React Query may require the use of alternative APIs to handle urgent and non-urgent updates effectively.
Understanding React’s Fiber Architecture
React Advanced 2022React Advanced 2022
29 min
Understanding React’s Fiber Architecture
Top Content
This Talk explores React's internal jargon, specifically fiber, which is an internal unit of work for rendering and committing. Fibers facilitate efficient updates to elements and play a crucial role in the reconciliation process. The work loop, complete work, and commit phase are essential steps in the rendering process. Understanding React's internals can help with optimizing code and pull request reviews. React 18 introduces the work loop sync and async functions for concurrent features and prioritization. Fiber brings benefits like async rendering and the ability to discard work-in-progress trees, improving user experience.
It's a Jungle Out There: What's Really Going on Inside Your Node_Modules Folder
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
The talk discusses the importance of supply chain security in the open source ecosystem, highlighting the risks of relying on open source code without proper code review. It explores the trend of supply chain attacks and the need for a new approach to detect and block malicious dependencies. The talk also introduces Socket, a tool that assesses the security of packages and provides automation and analysis to protect against malware and supply chain attacks. It emphasizes the need to prioritize security in software development and offers insights into potential solutions such as realms and Deno's command line flags.
A Practical Guide for Migrating to Server Components
React Advanced 2023React Advanced 2023
28 min
A Practical Guide for Migrating to Server Components
Top Content
Watch video: A Practical Guide for Migrating to Server Components
React query version five is live and we'll be discussing the migration process to server components using Next.js and React Query. The process involves planning, preparing, and setting up server components, migrating pages, adding layouts, and moving components to the server. We'll also explore the benefits of server components such as reducing JavaScript shipping, enabling powerful caching, and leveraging the features of the app router. Additionally, we'll cover topics like handling authentication, rendering in server components, and the impact on server load and costs.
Server Components: The Epic Tale of Rendering UX
React Summit 2023React Summit 2023
26 min
Server Components: The Epic Tale of Rendering UX
Top Content
Watch video: Server Components: The Epic Tale of Rendering UX
This Talk introduces server components in React, which provide an intermediate format for rendering and offer advantages for both client-side and server-side rendering. Server components reduce bundle size on the client and improve search engine optimization. They abstract the rendering process, allowing for faster rendering and flexibility in choosing where to render components. While server components are still in the experimental stage, Next.js is a good starting point to try them out.

Workshops on related topic

Concurrent Rendering Adventures in React 18
React Advanced 2021React Advanced 2021
132 min
Concurrent Rendering Adventures in React 18
Top Content
Featured WorkshopFree
Maurice de Beijer
Maurice de Beijer
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.
AI for React Developers
React Advanced 2024React Advanced 2024
142 min
AI for React Developers
Featured Workshop
Eve Porcello
Eve Porcello
Knowledge of AI tooling is critical for future-proofing the careers of React developers, and the Vercel suite of AI tools is an approachable on-ramp. In this course, we’ll take a closer look at the Vercel AI SDK and how this can help React developers build streaming interfaces with JavaScript and Next.js. We’ll also incorporate additional 3rd party APIs to build and deploy a music visualization app.
Topics:- Creating a React Project with Next.js- Choosing a LLM- Customizing Streaming Interfaces- Building Routes- Creating and Generating Components - Using Hooks (useChat, useCompletion, useActions, etc)
Getting Started with Suspense and Concurrent Rendering in React
React Summit 2020React Summit 2020
125 min
Getting Started with Suspense and Concurrent Rendering in React
Featured Workshop
Maurice de Beijer
Maurice de Beijer
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.
Build a Headless WordPress App with Next.js and WPGraphQL
React Summit 2022React Summit 2022
173 min
Build a Headless WordPress App with Next.js and WPGraphQL
Top Content
WorkshopFree
Kellen Mace
Kellen Mace
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.
Next.js 13: Data Fetching Strategies
React Day Berlin 2022React Day Berlin 2022
53 min
Next.js 13: Data Fetching Strategies
Top Content
WorkshopFree
Alice De Mauro
Alice De Mauro
- 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
Create a Visually Editable Next.js Website Using React Bricks, With Blog and E-commerce
React Summit 2023React Summit 2023
139 min
Create a Visually Editable Next.js Website Using React Bricks, With Blog and E-commerce
Top Content
WorkshopFree
Matteo Frana
Matteo Frana
- 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