fix(ratelimit): apply DB-defined rules at runtime + cover auth endpoints#206
Open
antosubash wants to merge 1 commit into
Open
fix(ratelimit): apply DB-defined rules at runtime + cover auth endpoints#206antosubash wants to merge 1 commit into
antosubash wants to merge 1 commit into
Conversation
Database-backed RateLimitRule rows were CRUD-only — admins could
create/edit/disable them but nothing applied them at request time, and
only one auth endpoint used the static "auth-strict" policy.
- Add IRateLimitRuleSource (Core) + RateLimitRuleCache (module) as a
singleton IHostedService that loads enabled rules into a volatile
snapshot and rebuilds on every admin write
- Wire options.GlobalLimiter to consult the cache per request and
partition by the matched rule; fall back to no-limit when nothing
matches the path
- Pattern matcher supports exact, prefix-wildcard, and "*" catch-all,
pre-computed at compile time to avoid per-request slicing
- Invalidate cache from Create/Update/Delete in RateLimitingService
- Apply .RateLimit("auth-strict") to LoginEndpoint, ForgotPasswordEndpoint,
ResetPasswordEndpoint, and OpenIddict /connect/token
- OnRejected branches to HTML for browser nav, JSON for API/Inertia,
using a new InertiaHttpExtensions helper (also dedupes 4 existing
raw "X-Inertia" header checks)
- Tighten CreateRequestValidator and add missing UpdateRequestValidator
so windowSeconds / segmentsPerWindow / token fields can no longer be
silently clamped from 0 by the cache
Deploying simplemodule-website with
|
| Latest commit: |
5e81b1a
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://08277b7f.simplemodule-website.pages.dev |
| Branch Preview URL: | https://ratelimit-fixes.simplemodule-website.pages.dev |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Database-backed
RateLimitRulerows were CRUD-only — admins could create/edit/disable them in the UI but nothing applied them at request time. Static named policies (auth-strict, etc.) existed but only one endpoint used them.IRateLimitRuleSource(Core) + internalRateLimitRuleCache(RateLimiting module) — a singletonIHostedServicethat loads enabled rules into a volatile snapshot on startup and rebuilds on every admin write.options.GlobalLimiterto resolve the matching rule per request from the cache and partition with the right limiter; falls back to no-limit when nothing matches the path.Exact,Wildcard(/api/users/*), andCatchAll(*); prefix/suffix pre-computed at compile time to avoid per-request slicing. Specificity sort ensures concrete patterns win over catch-alls.RateLimitingService.Create/Update/Deleteinvalidate the cache so admin edits take effect immediately..RateLimit("auth-strict")applied toLoginEndpoint,ForgotPasswordEndpoint,ResetPasswordEndpoint, and OpenIddict/connect/token— previously unprotected.InertiaHttpExtensions.IsInertia()helper that also dedupes 4 pre-existing raw"X-Inertia"callsites.UpdateRequestValidatorand tightenedCreateRequestValidatorso window/segment/token fields can no longer be silently clamped from 0 by the cache.Verification
/rate-limiting/managevia Playwright; Stored Rules + Active Policies tabs render; bothauth-strictandfixed-defaultshow in the active list./health/livewithpermitLimit=2, hammered the endpoint 5 times — got[200, 200, 429, 429, 429]. Deleted the rule and got a clean 204. Proves the cache, GlobalLimiter, and invalidation pipeline all work together.Test plan
RateLimitRuleCache.Matchesand theGlobalLimiterwiring inRateLimitingSetupauth-stricton the four auth endpoints is the right policy (10 req/min per IP)