限速器校验合格范围_限速

限速器校验合格范围

Rate limiting is an effective and relatively easy way to mitigate security risks. It will not be the only thing you do secure your applications, and it might not even be the most important thing you do to secure your applications, but it should ALWAYS be in your toolbox.

速率限制是缓解安全风险的有效且相对容易的方法。 保护应用程序不是唯一的事情,保护应用程序甚至不是最重要的事情,但是它应该始终在工具箱中。

Let’s take a case where an attacker tries to guess a user’s password. If you set a limit on the number of times a password can be attempted per day, it will cripple the hacker’s attack and keep your users safe.

让我们以攻击者试图猜测用户密码的情况为例。 如果您设置了每天可以尝试输入密码的次数的限制,它将削弱黑客的攻击并确保用户安全。

If you don’t rate limit, attackers can use your CPU and Memory to crack your users’ passwords!

如果您没有限制速率,攻击者可以使用您的CPU和内存来破解用户的密码!

If you accidentally allow users to read any arbitrary record from your database instead of only the records they should have access to, the problem will be much less severe if they can only read one un-authorised record per minute rather than extracting at 1000 records per minute.

如果您不小心允许用户从数据库中读取任意记录,而不是仅从他们应该访问的记录中读取数据,那么如果他们每分钟只能读取一个未经授权的记录,而不是每次提取1000条记录,那么问题就不会那么严重了。分钟。

Rate limiting makes the effects of being compromised less severe

速率限制使受损害的影响减轻

We’ll consider two good types of rate limiting in this post, but first let's look at a few examples that are bad but commonly used.

在本文中,我们将考虑两种很好的速率限制类型,但首先让我们看一些不好的但经常使用的示例。

固定窗口速率限制-请勿使用此功能 (Fixed Window Rate Limiting — Don’t Use This)

Fixed window rate limiting is very simple. You say something like — each user can make 10 requests to my API per hour. The implementation is simple:

固定窗口速率限制非常简单。 您说类似的话-每个用户每小时可以向我的API发出10个请求。 实现很简单:

  1. Keep a counter per user for the current hour

    在当前时间为每位用户保留一个计数器
  2. Increment the counter each time the user makes a request

    每次用户提出请求时增加计数器
  3. Reject the request if the counter is over the threshold

    如果计数器超过阈值,则拒绝请求
  4. Reset all the counters at the start of each hour

    每小时开始时重置所有计数器

The trouble is, this can be very frustrating and very unfair.

问题是,这可能非常令人沮丧并且非常不公平。

❌ Users who start making requests just before the hour ends get to make many more requests in the first few minutes than users who start making requests just as the hour has started.

the在小时结束之前开始发出请求的用户在开始的几分钟内会比在小时开始时开始发出请求的用户发出更多的请求。

❌ A user who uses more than you expected can be given a very harsh penalty. E.g. If I get to make 10 requests per hour, I can make 10 requests in under a second, but it takes over an hour to make 11 requests. That seems unfair.

uses使用量超出您预期的用户将受到严厉的处罚。 例如,如果我每小时可以发出10个请求,那么一秒钟之内可以发出10个请求,但是要花11个多小时才能完成。 那似乎不公平。

滑动窗口速率限制-请勿使用此功能 (Sliding Window Rate Limiting — Don’t Use This)

Here, instead of saying “you can make 10 requests in each hour, aligned to the hours on the clock” we say “you can make 10 requests in any period of an hour”. This means that if you make 2 requests per minute for half an hour, you then have to wait half an hour before you can make any more requests, at which point you can make up to 2 requests each minute for the next half hour.

在这里,我们说的是“您可以在一个小时的任何时间段内发出10个请求”,而不是说“您每小时可以与时钟中的小时保持一致,每小时可以发出10个请求”。 这意味着,如果您每分钟发出2个请求半小时,则必须等待半个小时才能发出更多请求,此时,接下来的半小时内每分钟最多可以发出2个请求。

✅ This feels much less unfair. Regardless of when you start making requests, you get the same deal.

✅感觉不那么公平了。 无论何时开始发出请求,您都将获得相同的交易。

❌ Unfortunately, it’s still easy to get in a situation where you have to wait a full hour to make any more requests, which really sucks.

❌不幸的是,遇到这样的情况仍然很容易,即您必须等待一个小时才能发出更多请求,这实在太糟糕了。

❌ To make this approach even worse, we now have to keep track of the timestamp of every request, in order to accurately account for how many requests the user is allowed to make.

❌为了使这种方法变得更糟,我们现在必须跟踪每个请求的时间戳,以便准确地说明允许用户发出多少个请求。

令牌桶速率限制 (Token Bucket Rate Limiting)

Token bucket rate limiting is a fairly easy system to implement. All you need is a counter representing how many “tokens” a user has, and a timestamp at which that count was last increased.

令牌桶速率限制是一个相当容易实现的系统。 您所需要的只是一个代表用户拥有多少“令牌”的计数器,以及该计数最后一次增加的时间戳。

The way this works is easiest to visualize as a bucket of tokens and a gate that requires a token to walk through. Each time we walk through the gate (make a request), we supply a token from the bucket.

它的工作方式最容易形象化为一桶令牌和需要令牌通过的门。 每次我们穿过大门(发出请求)时,我们都会从存储桶中提供令牌。

Image for post
Removing a token from the bucket to pass through the gate
从桶中取出令牌以通过门

If we keep walking through the gate (making requests), we’ll eventually run out of tokens.

如果我们继续穿过大门(发出请求),最终将用光令牌。

Image for post
Using the last token
使用最后一个令牌

Now when we try to make one more request, we won’t be able to, because we’ve run out of tokens.

现在,当我们尝试再提出一个请求时,由于令牌用完,我们将无法执行请求。

Image for post
There are no more tokens left
没有更多的令牌了

Fortunately, while we’re busy taking tokens to make the request, another background process is adding a token at a set interval. e.g. if we stick to our 10 requests per hour model, a token is added every 6 minutes

幸运的是,当我们正忙着使用令牌来发出请求时,另一个后台进程正在按设定的时间间隔添加令牌。 例如,如果我们坚持每小时10个请求模型,则每6分钟添加一个令牌

Image for post
1 token every 6 minutes
每6分钟1个令牌

This means that the most we have to wait between one request and the next is 6 minutes, which feels much fairer.

这意味着我们在一个请求和下一个请求之间需要等待的最长时间为6分钟,这感觉要公平得多。

As long as we don’t make requests more than once every 6 minutes on average, we’ll never run out of tokens. If we make requests less frequently than once every 6 minutes, eventually the bucket will fill up with tokens. At that point, any new tokens will fall out of the bucket and be lost.

只要我们平均每6分钟发出一次请求不超过一次,我们就永远不会用完令牌。 如果我们发出请求的频率少于每6分钟一次,那么存储桶最终将充满令牌。 届时,任何新代币都会掉出水桶并丢失。

Image for post
The bucket of tokens overflowing
一桶令牌溢出

The size of the bucket controls how “bursty” we’re allowed to be, and the frequency with which tokens are added controls the maximum rate of requests we’re allowed to sustain over the long term. E.g. if the bucket size is 10 and a new token is added once every 6 minutes, we can make 20 requests in the first hour (up to 10 in the first instant, then 1 every 6 minutes), but if we do that we’ll only be able to make 1 request every 6 minutes from then on. In the long run, this works out about the same as just allowing 10 requests per hour.

存储桶的大小控制着我们被允许的“突发性”程度,添加令牌的频率控制着我们允许长期维持的最大请求速率。 例如,如果存储桶大小为10,并且每6分钟添加一次新令牌,则我们可以在第一个小时内发出20个请求(在第一瞬间最多发出10个请求,然后每6分钟发出1个请求),但是如果我们这样做,此后每6分钟只能发出1个请求。 从长远来看,这相当于每小时只允许10个请求。

✅ This is fair regardless of when you start making requests — A new bucket is allocated on your first request

✅无论何时开始发出请求,这都是公平的-在第一个请求上分配了一个新存储桶

✅ This is never punitive — The most you’ll ever have to wait is the time between tokens being added

never这绝不是惩罚性的-您最多需要等待的是添加令牌之间的时间

✅ This is efficient to implement — All you need to store is a timestamp and a token count for each user

to这实现起来很有效—您需要存储的只是每个用户的时间戳和令牌计数

The code for implementing rate limiting from scratch in JavaScript is only about 35 lines (with comments):

在JavaScript中从零开始实现速率限制的代码只有大约35行(带注释):

Image for post
Implementation of Bucket Rate Limiting
实施桶限速

Open On Code Sandbox

在代码沙箱上打开

Note: This method is also sometimes called “Leaky Bucket” rate limiting, but that metaphor is much more confusing in my opinion.

注意:这种方法有时也称为“泄漏桶”速率限制,但是在我看来,这种隐喻更加令人困惑。

指数延迟率限制 (Exponential Delay Rate Limiting)

The other type of rate limiting you should be familiar with is “exponential delay”. This is only appropriate where:

您应该熟悉的另一种速率限制是“指数延迟”。 这仅适用于以下情况:

  • You want to be punitive with what you perceive as abuse

    您想对自己认为是虐待的行为进行惩罚
  • You have a natural point to “reset” the rate limit

    您自然有必要“重置”速率限制

There’s pretty much just one use case for exponential delay, and that’s passwords.

指数延迟几乎只有一个用例,那就是密码

The wrong way to handle passwords is to just lock people out after a certain number of attempts. This has two issues:

处理密码的错误方法是在尝试一定次数后才将人们拒之门外。 这有两个问题:

  1. It’s easy to get permanently locked out of your account if you forget your password.

    如果您忘记了密码,很容易将帐户永久锁定。
  2. Someone else can abuse this feature to permanently lock you out of your account, and they can do so very quickly.

    其他人可能会滥用此功能将您永久性地锁定在您的帐户之外,而且他们可以很快地这样做。

Exponential rate limits don’t have either of these problems, at least not to the same extent.

指数速率限制没有这些问题,至少没有达到同样的程度。

With an exponential rate limit, the first few attempts are quick, and then subsequent attempts rapidly take longer and longer. An attacker trying to use brute force will end up needing an eternity to try sufficiently different passwords, and an attacker trying to deny legitimate users access will need to spend just as long of time if they want to lock the user out for extended periods.

在具有指数速率限制的情况下,前几次尝试很快,然后随后的尝试Swift花费的时间越来越长。 试图使用蛮力的攻击者最终将需要永恒的努力来尝试使用足够不同的密码,而试图拒绝合法用户访问的攻击者如果想要将用户锁定更长的时间,则需要花费等长的时间。

The code for exponential delay is even simpler than for bucket rate limiting, and our takeToken function is exactly as before.

指数延迟的代码甚至比限制存储桶速率更简单,我们的takeToken函数与以前完全一样。

Image for post
Implementation of Exponential Delay Rate Limiting
指数延迟速率限制的实现

Open On Code Sandbox

在代码沙箱上打开

结论 (Conclusion)

  • Use bucket rate limiting to secure APIs because it’s fair and proportional for legitimate users while restricting abusive users.

    使用存储桶速率限制来确保API的安全,因为它对合法用户是公平且成比例的,同时可以限制滥用用户。
  • Use exponential delay rate limiting for passwords and reset the delay after any successful login.

    对密码使用指数延迟速率限制,并在成功登录后重置延迟。
  • You should apply a bucket rate limit per IP address before applying the exponential rate limit by username to prevent someone having a go at every username with the same password.

    您应先按IP地址应用存储桶速率限制,然后再按用户名应用指数速率限制,以防止有人使用相同的密码访问每个用户名。

If you’re using Node.js, and you don’t fancy maintaining your own rate limiting implementations (which you absolutely shouldn’t) you can use mine: https://www.atauthentication.com/docs/rate-limit

如果您使用的是Node.js,并且不想维护自己的速率限制实现(绝对不应该这样做),则可以使用我的: https : //www.atauthentication.com/docs/rate-limit

翻译自: https://levelup.gitconnected.com/rate-limiting-a0783293026a

限速器校验合格范围

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值