Add Strict CSP Headers (#243)

* Add CSP nonce support and enhance security headers

Introduced secure headers and CSP nonce to improve app security by integrating `@nosecone/next`. Updated middleware, root providers, and layout to handle nonce propagation, enabling stricter CSP policies when configured. Also upgraded dependencies and tooling versions.

* Add OTP and security guidelines documentation and additional checks on client-provided values

- Introduced additional checks on client-provided values such as cookies
- Introduced a new OTP API documentation outlining the creation and verification of OTP tokens for sensitive operations.
- Added comprehensive security guidelines for writing secure code in Next.js, covering client and server components, environment variables, authentication, and error handling.

These additions enhance the project's security posture and provide clear instructions for developers on implementing secure practices.
This commit is contained in:
Giancarlo Buomprisco
2025-04-22 09:43:21 +07:00
committed by GitHub
parent 903ef6dc08
commit db9ddab6ad
9 changed files with 312 additions and 15 deletions

View File

@@ -24,7 +24,8 @@ const getUser = (request: NextRequest, response: NextResponse) => {
};
export async function middleware(request: NextRequest) {
const response = NextResponse.next();
const secureHeaders = await createResponseWithSecureHeaders();
const response = NextResponse.next(secureHeaders);
// set a unique request ID for each request
// this helps us log and trace requests
@@ -59,7 +60,7 @@ export async function middleware(request: NextRequest) {
async function withCsrfMiddleware(
request: NextRequest,
response = new NextResponse(),
response: NextResponse,
) {
// set up CSRF protection
const csrfProtect = createCsrfProtect({
@@ -100,7 +101,7 @@ async function adminMiddleware(request: NextRequest, response: NextResponse) {
const isAdminPath = request.nextUrl.pathname.startsWith('/admin');
if (!isAdminPath) {
return response;
return;
}
const {
@@ -222,3 +223,21 @@ function matchUrlPattern(url: string) {
function setRequestId(request: Request) {
request.headers.set('x-correlation-id', crypto.randomUUID());
}
/**
* @name createResponseWithSecureHeaders
* @description Create a middleware with enhanced headers applied (if applied).
* This is disabled by default. To enable set ENABLE_STRICT_CSP=true
*/
async function createResponseWithSecureHeaders() {
const enableStrictCsp = process.env.ENABLE_STRICT_CSP ?? 'false';
// we disable ENABLE_STRICT_CSP by default
if (enableStrictCsp === 'false') {
return {};
}
const { createCspResponse } = await import('./lib/create-csp-response');
return createCspResponse();
}