Open patrickn2 opened 1 year ago
You can selectively enable edge-csrf only for certain routes in the middleware file:
// middleware.ts
import csrf from 'edge-csrf';
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
// initalize protection function
const csrfProtect = csrf({
cookie: {
secure: process.env.NODE_ENV === 'production',
},
});
export async function middleware(request: NextRequest) {
const response = NextResponse.next();
if request.url.startsWith('/api/') {
// csrf protection
const csrfError = await csrfProtect(request, response);
// check result
if (csrfError) {
return new NextResponse('invalid csrf token', { status: 403 });
}
}
return response;
}
This solution is url based so it will run both GET and POST requests through the edge-csrf middleware.
The problem with this code is that I need to protect my GET api routes and if you execute this code, the other pages will not create the csrfToken to pass to my api route.
The method csrfProtect needs to be executed all times
You might be able to hack together a solution with edge-csrf
but this library is designed to generate CSRF tokens on GET's and validate them on POST's so it doesn't sound like it will work for you. Are you sure there isn't a way to use POST handlers on your API routes?
These API routes are only to get some data, so I don't think using POST is a good idea. If the owner could not give me a solution I will try to find another package :(
OWASP guidance is to consider GET, HEAD, and OPTIONS as safe methods that do not need to be appended with a CSRF token and POST, PUT, PATCH, and DELETE methods, as state changing verbs that should have a CSRF token attached to the request. If you're using javascript you can use fetch()
to send data via POST easily.
My ideia is to make it harder to crawlers/bots fetch my data, I know that this will not make it impossible to fetch the data but I want to make it harder adding a csrf validation.
You can selectively enable edge-csrf only for certain routes in the middleware file:
// middleware.ts import csrf from 'edge-csrf'; import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; // initalize protection function const csrfProtect = csrf({ cookie: { secure: process.env.NODE_ENV === 'production', }, }); export async function middleware(request: NextRequest) { const response = NextResponse.next(); if request.url.startsWith('/api/') { // csrf protection const csrfError = await csrfProtect(request, response); // check result if (csrfError) { return new NextResponse('invalid csrf token', { status: 403 }); } } return response; }
This solution is url based so it will run both GET and POST requests through the edge-csrf middleware.
Hello, do this also apply if I only need to have the edge-csrf enabled on api routes. I have supabase and I don't need the csrf but only on the api routes alone.
Hello, do this also apply if I only need to have the edge-csrf enabled on api routes. I have supabase and I don't need the csrf but only on the api routes alone.
If you only want to apply it to API routes then you can use the same strategy but looking the code again I would suggest doing this instead in order for the cookie to get set on non-api GET requests:
export async function middleware(request: NextRequest) {
const response = NextResponse.next();
// csrf protection
const csrfError = await csrfProtect(request, response);
// check result
if (csrfError && request.url.startsWith('/api/')) {
return new NextResponse('invalid csrf token', { status: 403 });
}
return response;
}
I would like to protect only my /api/ path, this means that I want to protect the GET method also If I don't ignore the GET method, the csrf token will not be created and inserted in the header of a normal page.
How to work around this?