You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
According to the documentation, the RedisTokenBucketRateLimiter is supposed to refill the bucket by TokensPerPeriod every ReplenishmentPeriod until TokenLimit is reached. Because refilling the bucket is no constant process, this is done whenever the rate limit is accessed through the Lua script.
To prevent stale rate limit entries in Redis, the Lua script calculates and sets a TTL for the rate limit keys:
The calculated TTL, however, does not seem to be correct. fill_time is the number of ReplenishmentPeriods it takes, until the bucket is full again. This leads to a valid TTL if ReplenishmentPeriod is less than 2 seconds. But in case the ReplenishmentPeriod is higher, like 15 seconds, the TTL is wrong. Which, in case no requests occur for the duration of the TTL, leads to a bucket which is filled early.
While looking into this issue a bit more, I also discovered another issue:
When the ReplenishmentPeriod is higher than the interval in which clients access the API, each request will update the @timestamp_key in the database even though @rate_limit_key remains the same. The latter is because current_tokens is always an integer and math.floor() is used to avoid granting too many tokens. The result, however, is that a client which exceeded his quota and keeps making requests is locking himself out infinitely.
I'm actually surprised that no one else noticed so far...
Thanks! I noticed this too and couldn't work it out. I pulled down your fork and it works as expected.
Would love if @cristipufu could have a look at it.
According to the documentation, the
RedisTokenBucketRateLimiter
is supposed to refill the bucket byTokensPerPeriod
everyReplenishmentPeriod
untilTokenLimit
is reached. Because refilling the bucket is no constant process, this is done whenever the rate limit is accessed through the Lua script.To prevent stale rate limit entries in Redis, the Lua script calculates and sets a TTL for the rate limit keys:
aspnetcore-redis-rate-limiting/src/RedisRateLimiting/TokenBucket/RedisTokenBucketManager.cs
Lines 40 to 41 in 6824756
The calculated TTL, however, does not seem to be correct.
fill_time
is the number ofReplenishmentPeriod
s it takes, until the bucket is full again. This leads to a valid TTL ifReplenishmentPeriod
is less than 2 seconds. But in case theReplenishmentPeriod
is higher, like 15 seconds, the TTL is wrong. Which, in case no requests occur for the duration of the TTL, leads to a bucket which is filled early.Example of a problematic rate limiter:
The fix for this should be simple, but I'll have to look into it.
The text was updated successfully, but these errors were encountered: