Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there any way to protect only a specific path? #11

Open
patrickn2 opened this issue Jul 10, 2023 · 8 comments
Open

Is there any way to protect only a specific path? #11

patrickn2 opened this issue Jul 10, 2023 · 8 comments

Comments

@patrickn2
Copy link

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?

@amorey
Copy link
Member

amorey commented Jul 12, 2023

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.

@patrickn2
Copy link
Author

patrickn2 commented Jul 12, 2023

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

@amorey
Copy link
Member

amorey commented Jul 13, 2023

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?

@patrickn2
Copy link
Author

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 :(

@amorey
Copy link
Member

amorey commented Jul 13, 2023

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.

@patrickn2
Copy link
Author

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.

@devrenzz
Copy link

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.

@amorey
Copy link
Member

amorey commented Feb 15, 2024

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;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants