# next-safe-middleware
**Repository Path**: ProjectOpenSea/next-safe-middleware
## Basic Information
- **Project Name**: next-safe-middleware
- **Description**: Strict CSP (Content-Security-Policy) for Next.js hybrid apps https://web.dev/strict-csp/
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2022-09-13
- **Last Updated**: 2025-06-20
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
@next-safe/middleware
Strict Content-Security-Policy (CSP) for Next.js with composable middleware
Works for hybrid apps and supports pages with any data fetching method.
Always sets CSP by HTTP Response header and enables easy setup of reporting.
[![Version][version-badge]][package]
[![Downloads][downloads-badge]][npmtrends]
[![MIT][license-badge]][license]
[![Release][release-status-badge]][release-status]

[![Star on GitHub][github-star-badge]][github-star]
[![Watch on GitHub][github-watch-badge]][github-watch]
[![Forks on GitHub][github-forks-badge]][github-forks]
[package]: https://npmjs.com/package/@next-safe/middleware
[npmtrends]: https://www.npmtrends.com/@next-safe/middleware
[version-badge]: https://img.shields.io/npm/v/@next-safe/middleware.svg?style=flat-square
[downloads-badge]: https://img.shields.io/npm/dm/@next-safe/middleware.svg?style=flat-square
[license]: LICENSE
[license-badge]: https://img.shields.io/github/license/nibtime/next-safe-middleware?style=flat-square
[release-status]: https://github.com/nibtime/next-safe-middleware/actions/workflows/release.yml
[release-status-badge]: https://img.shields.io/github/workflow/status/nibtime/next-safe-middleware/Release?style=flat-square&label=release
[github-watch]: https://github.com/nibtime/next-safe-middleware/watchers
[github-watch-badge]: https://img.shields.io/github/watchers/nibtime/next-safe-middleware.svg?style=social
[github-star]: https://github.com/nibtime/next-safe-middleware/stargazers
[github-star-badge]: https://img.shields.io/github/stars/nibtime/next-safe-middleware.svg?style=social
[github-forks]: https://github.com/nibtime/next-safe-middleware/network/members
[github-forks-badge]: https://img.shields.io/github/forks/nibtime/next-safe-middleware.svg?style=social
## What
This package strives to make the setup and deployment of a [Strict Content Security Policy (CSP)
](https://web.dev/strict-csp/) with Next.js an easy task. The design approach that makes this possible requires [Next.js Middleware](https://nextjs.org/docs/advanced-features/middleware), which has been introduced as Beta in [Next.js 12](https://nextjs.org/blog/next-12) and is stable since [Next.js 12.2](https://nextjs.org/blog/next-12-2).
This package handles all Strict CSP conundrums for you and works for:
* pages with [`getStaticProps`](https://nextjs.org/docs/basic-features/data-fetching/get-static-props) - **Hash-based**
* pages with [`getServerSideProps`](https://nextjs.org/docs/basic-features/data-fetching/get-server-side-props) - **Nonce-based**
* pages with [`getStaticProps` + `revalidate` (ISR)](https://vercel.com/docs/concepts/next.js/incremental-static-regeneration) - **Hash-based**
**This package always sets CSP as HTTP response header**. That enables violation reporting and report-only mode even for static pages. Plus, it provides a middleware and API handlers that make the setup of CSP violation reporting very easy.
## Why
Configuring and maintaining a [Content-Security-Policy (CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) can be a tedious and error prone task. Furthermore, classic CSPs with a whitelist approach don't give you the security you might think you get from them, because in a lot of cases, they are automatically bypassable.
There is a much better option: a [**Hash-based/Nonce-based Strict CSP**](https://web.dev/strict-csp/).
Such CSPs provide much better security and have always the same structure, so they don't need the maintenance that whitelist CSPs need, once they've been set up properly. But this setup is usually a a very big issue with Next.js (and with all web frameworks in general).
This is where this package comes in: To make this setup easy, convenient and a lot less error-prone.
### Good Resources about (Strict) Content-Security-Policy (CSP)
* The best overview on Strict CSPs: https://web.dev/strict-csp/
* Great slides from a conference talk, has lots of insights and field data: https://static.sched.com/hosted_files/locomocosec2019/db/CSP%20-%20A%20Successful%20Mess%20Between%20Hardening%20and%20Mitigation%20%281%29.pdf
* Great view on CSPs from an attacker's perspective: https://book.hacktricks.xyz/pentesting-web/content-security-policy-csp-bypass
* Good explanation of the `strict-dynamic` keyword: https://content-security-policy.com/strict-dynamic/
* Indispensible for testing: [The CSP Evaluator Extension for Google Chrome](https://chrome.google.com/webstore/detail/csp-evaluator/fjohamlofnakbnbfjkohkbdigoodcejf?hl=de)
* Great tool to record CSP sources by browsing your site: [The Laboratory Extension for Mozilla Firefox](https://addons.mozilla.org/en-US/firefox/addon/laboratory-by-mozilla/)
## Getting started
Install `@next-safe/middleware` from NPM
```bash
npm -i @next-safe/middleware
```
```bash
yarn add @next-safe/middleware
```
### Quickstart: Strict Content-Security-Policy (CSP)
Create the file `middleware.js` in your Next.js project folder:
```js
// middleware.js
import {
chainMatch,
isPageRequest,
csp,
strictDynamic,
} from "@next-safe/middleware";
const securityMiddleware = [
csp({
// your CSP base configuration with IntelliSense
// single quotes for values like 'self' are automatic
directives: {
"img-src": ["self", "data:", "https://images.unsplash.com"],
"font-src": ["self", "https://fonts.gstatic.com"],
},
}),
strictDynamic(),
];
export default chainMatch(isPageRequest)(...securityMiddleware);
```
Create the file `pages/_document.js` in your Next.js project folder:
```jsx
// pages/_document.js
import {
getCspInitialProps,
provideComponents,
} from "@next-safe/middleware/dist/document";
import Document, { Html, Main } from "next/document";
export default class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await getCspInitialProps({ ctx });
return initialProps;
}
render() {
const { Head, NextScript } = provideComponents(this.props);
return (