sveltejs / kit

web development, streamlined
https://kit.svelte.dev
MIT License
18.46k stars 1.89k forks source link

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

Open swyxio opened 1 year ago

swyxio commented 1 year ago

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 commented 1 year ago

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

Rich-Harris commented 1 year ago

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?

swyxio commented 1 year ago

(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

antony commented 1 year ago

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.

rnbokade commented 1 year ago

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.

ciscoheat commented 1 year ago

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

rnbokade commented 1 year ago

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.

jesuscovam commented 1 year ago

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?

CaptainCodeman commented 6 months ago

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: