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

Support for enabling middlewares for api endpoints #392

Closed
MickL opened this issue Mar 4, 2024 · 11 comments · Fixed by #429
Closed

Support for enabling middlewares for api endpoints #392

MickL opened this issue Mar 4, 2024 · 11 comments · Fixed by #429
Labels
enhancement New feature or request

Comments

@MickL
Copy link

MickL commented Mar 4, 2024

Setting rateLimiter for a specific api route doest seem to have any effect:

File: /api/login.post.ts

Nuxt Config:

routeRules: {
    '/api/login': {
      security: {
        rateLimiter: {
          tokensPerInterval: 2,
          interval: 1000 * 60,
        },
      },
    },
  }

It works for get (/api/login.ts) but not for post (/api/login.post.ts).

Version

nuxt-security: 1.2.1
nuxt: 3.10.3

Reproduction Link

https://stackblitz.com/edit/baroshem-nuxt-security-irwi3r?file=nuxt.config.ts

@MickL MickL added the bug Something isn't working label Mar 4, 2024
@Baroshem
Copy link
Owner

Baroshem commented Mar 5, 2024

Hey Buddy!

Thanks for creating this issue.

However, I dont think that it is a bug because built in rate limiting is supposed to work for routes alrather than endpoints. It utilizes the routeRules to create rules for certain route. And your post request is not a route but it is an endpoint that you send a Post request.

So I think that in order to make it work, we would need to modify the current global configuration of the module to allow it to work on certain endpoints.

It could be something like this:

security: {
  rateLimiter: {
    tokensPerInterval: 100, // other configuration
    endpoints: ['/api/login']
  }
}

But at this point, I think we should also support exclude/include as sometimes you may have multiple endpoints so it could be easier to just mention which ones should/shouldnt be rate limited.

@vejja what are your thoughts on that? This is probably a global change that should also work for other middlewares like request size, xss, etc

@Baroshem Baroshem added enhancement New feature or request and removed bug Something isn't working labels Mar 5, 2024
@Baroshem Baroshem changed the title rateLimiter doesnt work for post routes Support for enabling middlewares for api endpoints Mar 5, 2024
@MickL
Copy link
Author

MickL commented Mar 5, 2024

So it doesnt work with routeRoules to configure specific api routes? Because thats what I already did with other nuxt-security config options. E.g. I disabled XSS for some speicific routes, but there I used /api/products/**/images.

The problem with your supposed solution is that I want to have very low tokens per interval for my /api/login endpoint (e.g. 5 tries per minute) but keep the default for the rest of my application.

Further I was kinda expecting that the IP gets blocked just for this route, too but with the get route I figured the rateLimiter is blocking everything once blocked.

Thanks for the quick response btw :)

@vejja
Copy link
Collaborator

vejja commented Mar 5, 2024

Hi @Baroshem

OP is willing to limit 5 requests/minute on a specific route /api/products/**/images, but wants to keep the default for the rest of the application.
Our current implementation counts the number of requests per IP, and not per route. So once OP hits 5 requests on /api/products/**/images, the rateLimiter flags the IP as over-the-limit and denies any subsequent request for all of the application.

I tried to get my head over this in #292 but I realized that a rate limiter is a complex piece of software. You would want to handle correctly both IP rules and route logic.

My view is that our Rate Limiter is a basic implementation for very simple use cases. Users that want to have a fully-fledged rate limiter should probably use a dedicated module. In #357 user @fayazara mentioned https://github.com/timb-103/nuxt-rate-limit. I have no experience with this module though.

On the other hand we might want to develop a more complete version of the rateLimiter. It would be great, but I think it will require a substantial effort.

@Baroshem
Copy link
Owner

Baroshem commented Mar 5, 2024

@vejja thanks for your input.

I actually based the new implementation of Nuxt Security Rate Limiting on the nuxt rate limit kodule you mentioned. Unless there were several changes there, I think this module delivers similiar value.

Basically, it is really difficult to handle rate limiting on the application level while it should be handled on the infrastructure level instead.

We can work on the rate limiter to make it a bit better but I dont rhink that we can make it as efficient as ready solutions like Cloudflare.

What do you say? Should we work on the support for the features you mentioned? :)

@MickL
Copy link
Author

MickL commented Mar 5, 2024

I would definitely appreciate a more advanced solution for nuxt-security :) Looking at nuxt-rate-limit it provides a default for /api/** which can then be overwritten. This is what I would love to see from nuxt-security aswell. Unfortunately the module doesnt seem to provide the broad driver support that nuxt-security does.

On the other hand Vercel also recommends to build a middleware that runs before the request reaches the application: https://vercel.com/guides/rate-limiting-edge-middleware-vercel-kv - This agrees with you saying it should be done on the infrastructure level instead.

A common use case is to protect certain routes from brute force attacks, e.g. guessing login passwords, reset tokens, etcc

@vejja
Copy link
Collaborator

vejja commented Mar 5, 2024

I do agree it should be handled at infrastructure level

@Baroshem
Copy link
Owner

That would be a perfect scenario, yes. But for the people who want to use our module, I think we should work on imrpving the rate limiter to atleast allow users to rafe limit api endpoints.

@MickL would you be interested in creating a proof of concept of such solution? :)

@MickL
Copy link
Author

MickL commented Mar 24, 2024

Sorry but I am not really suitable for creating security features and rely on libraries like this.

I wanted to add to the discussion that AdonisJS has very fine grained control over rate limiting, maybe it could be a nice reference: https://docs.adonisjs.com/guides/rate-limiter

@Baroshem
Copy link
Owner

Thanks for the asditional inout @MickL !

I can take it from here.

If I understand correclty, we would need two new additions to the rate limiting api:

  1. Support for route based rate limiting. For that I would recommend to create a new config property like limitByRoutes which will then store in the database (or memory) IP's with the corresponding route so that we can achieve the case of being blocked on certain route only and do not block the usage on other routes. @vejja would that work for the case you mentioned?
  2. Support rate limiting for api endpoints that will be separate from the route rules that we have as of now. We could create a configuration option like api and inside of it exclude and include which would corectly set the rate limiting rules for appriopriate api endpoints. Would that work for you @MickL ?

Thanks for all the input guys!

@vejja
Copy link
Collaborator

vejja commented Mar 25, 2024

  1. Support for route based rate limiting. For that I would recommend to create a new config property like limitByRoutes which will then store in the database (or memory) IP's with the corresponding route so that we can achieve the case of being blocked on certain route only and do not block the usage on other routes. @vejja would that work for the case you mentioned?

Yes, I think it would

  1. Support rate limiting for api endpoints that will be separate from the route rules that we have as of now. We could create a configuration option like api and inside of it exclude and include which would corectly set the rate limiting rules for appriopriate api endpoints. Would that work for you @MickL ?

Is there a chance we could treat the routes and the api endpoints as if they were the same thing ? I suppose both are being served by Nitro anyways, right ?
Nuxt documentation does not seem to make a difference in the definition of routeRules

@Baroshem
Copy link
Owner

Baroshem commented Apr 4, 2024

@vejja

Regarding point 1. I think even better approach would be to introduce config property limitStrategy that could have a value of global (default) or per-route which will be a new addition

About point 2. I think that it would work like that. I will do some research and let you know :)

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

Successfully merging a pull request may close this issue.

3 participants