kit icon indicating copy to clipboard operation
kit copied to clipboard

[Feature Request] Default/Easy Rate Limit strategy on all API routes

Open swyxio opened this issue 2 years ago • 5 comments

Describe the problem

rate limiting is a basic security problem that is left up to the developer. but it really shouldn't be, particularly for a backend/fullstack framework.

not handling this by default makes sveltekit apps with any significant api/backend calls extremely prone to Denial of Service/Denial of Wallet attacks out of the box.

Describe the proposed solution

it should be as easy as it is in comparable ecosystems:

Alternatives considered

do nothing, almost guarantee nobody is doing this well if at all

Importance

nice to have

Additional Information

the next obvious need will be to document/pave the path of how to do the rate limiting on a per user or per team basis while letting other users/teams proceed

swyxio avatar Jan 28 '23 05:01 swyxio

i implemented this https://github.com/vercel/next.js/blob/canary/examples/api-routes-rate-limit/utils/rate-limit.ts but it should be default/easier/documented

swyxio avatar Jan 28 '23 06:01 swyxio

This is where the Railses and the Djangos of the world have an advantage, being properly coupled to a backend — the logic part is easy (would be trivial to implement as a handle hook, whether as a third party thing or exported from @sveltejs/kit/hooks), it's the storage that's difficult. In a serverless context we obviously can't just rely on an in-memory store. Any thoughts on how to approach that?

Rich-Harris avatar Jan 28 '23 14:01 Rich-Harris

(in case anyone reading this didnt know, in-memory is obviously janky but also works for low concurrency, non-edge serverless https://twitter.com/swyx/status/1230731059903336448?s=20)

yeah so i acknowledge that the infra layer should give us more to work with here. perhaps something that vercel could push the envelope on internally that sveltekit can then use? (this really is a pervasive flaw in fully serverless systems). also notable that simple storage apis are built into deno and cloudflare workers.

i was toying with some kind of etag based timestamp hashing approach but i dont think itd lead to the right rate limiting experience :/

anyway i do feel strongly that backends calling any kind of api where potentially serious money is on the line (eyes my openai bill) should have default rate limiting so i figured i’d file this issue. it’s understandable if we cant solve this for now but feels like a material thing that someone will have to solve at some point for serverless to be a thing

swyxio avatar Jan 28 '23 17:01 swyxio

This would probably be a good use-case for https://vercel.com/dashboard/stores, given the very little I know about them - though - I understand that this happens on the edge, so isn't a whole solution, and of course, it poses the age-old question about how we would emulate/test this locally.

Then there's the even older question about implementing things which work across all platforms equally. We could provide adapter specific config for this, but what would the syntax look like when we're trying not to build something specific to vercel, or the edge.

antony avatar Jan 28 '23 18:01 antony

I found this blog by upstash https://upstash.com/blog/sveltekit-rate-limiting Which made me think, we can have this implemented with selectable strategy. It could be Redis based if user wants to do serverless, it could be platform specific KV based like cloudflare KV or vercel kv or it could be some sort of inmemory store on single node server (syncing state in multinode deployment with loadbalancing would be difficult). Maybe we can have the configurable options linked to adapter used as well. Idk much about core svelte I am just a beginner level svelte dev. But just putting out my ideas.

rnbokade avatar May 25 '23 15:05 rnbokade

Here's a rate limiter library that may be useful in the meantime: https://github.com/ciscoheat/sveltekit-rate-limiter

ciscoheat avatar Aug 11 '23 09:08 ciscoheat

Ok so I have a proposal... I found this library called Unstorage https://github.com/unjs/unstorage which provides uniform api across different types of KV stores. Can we modify @upstash 's implementation of rate limit to work with this and then put is as a core utility in sveltekit..... So devs are free to use any type of storage they want. Depending on their platform.

rnbokade avatar Aug 15 '23 12:08 rnbokade

Is it ok to use this example https://vercel.com/guides/rate-limiting-edge-middleware-vercel-kv with hooks.server.js and target the '/api/*' routes?

jesuscovam avatar Sep 11 '23 16:09 jesuscovam

I had a need for rate-limiting, but also coupled with an API key token system, and came up with this: https://www.npmjs.com/package/svelte-api-keys

Still working on tidy-up and a proper demo page but the TL;DR is that it works similar to GitHub Fine-Grained Personal Access tokens:

  • The generated API key is only displayed once / never stored
  • Keys can be associated with multiple permissions or scopes
  • Approval of each call is based on the key permissions, any expiry date, plus token-bucket rate-limiting
  • Rate limits can apply globally for the entire API or per group or individual endpoints (and limits are based on key owner, not the key itself, so people could create and manage their own keys)
  • Token bucket implementations are in-memory (OK-ish for dev / single server) or Redis Stack
  • Key storage is a simple interface, with in-memory (suitable for dev / demo use only), Redis and Firestore implementations
  • LRU cache with TTL saves on database hits for key info lookups
  • You can layer on tier-based rate limits as well, again, similar to how Github works

CaptainCodeman avatar Mar 22 '24 23:03 CaptainCodeman