狗食我们自己的限速API


117

概述:

我公司开发了一个限速API。我们的目标是双重的:

  • 答:围绕我们的产品创建一个强大的开发者生态系统。
  • B:通过使用它来驱动我们自己的应用程序,展示我们API的强大功能。

澄清:为什么完全要限制速率?

我们对API进行了等级限制,因为我们将其作为产品的附加产品出售。匿名访问我们的API的每小时API调用阈值非常低,而我们的付费客户每小时可以允许1000个以上的调用。

问题:

我们的限速API非常适合开发人员生态系统,但是为了让我们陷入困境,我们不能将其限制为相同的限速。我们的API的前端全部是JavaScript,可直接对API进行Ajax调用。

所以问题是:

您如何保护api,以便可以删除速率限制,而在删除速率限制的过程中不容易被欺骗?

探索的解决方案(以及为什么它们不起作用)

  1. 针对主机标头验证引荐来源网址。- 有缺陷,因为引荐来源网址很容易被伪造。

  2. 使用HMAC根据请求和共享机密创建签名,然后在服务器上验证请求。- 有缺陷,因为可以通过查看前端JavaScript轻松确定机密和算法。

  3. 代理请求并在代理中签名请求- 仍然存在缺陷,因为代理本身公开了API。

问题:

我期待Stack Overflow的杰出人才提出替代解决方案。您将如何解决这个问题?


13
你不能 如果您不希望自己受限于速率限制的API的使用只是来自公共网页,那么您就无法对这些公共网页进行任何安全的操作,因为您似乎已经知道,公共网页上没有秘密。因此,您可以在网页中做什么,其他人也可以。
jfriend00

28
您确定在使用Dogfood时确实存在要解决的限速问题吗?使用您的网站和网页的每个用户应该看起来与您的限速代码完全不同。因此,只要确保每个网页本身都遵循正常的速率限制规则,就可以了。假设您的速率限制是针对每个客户的,那么一个用户将不会与任何其他用户有任何关系。
jfriend00

6
您为什么不考虑针对每个用户,每个角色/权限或应用程序范围提供速率限制和限制的API管理解决方案。例如wso2 api管理员
MiddlewareManiac


28
您的狗食行为发现了您的公共API的一个严重问题(即速率限制太低),您没有解决它,而是在设法解决它。如果您要忽略发现的问题,为什么选择狗粮呢?
user253751 '16

Answers:


93

由于您自己的JavaScript客户端直接访问API,因此任何人都可以查看它的作用并进行模仿,包括使用相同的API密钥。您可以尝试使其变得更困难,例如通过混淆代码或设置各种障碍,但是您和您要限制的人在根本上具有相同的访问权限。无需尝试在特权上造成差异,您需要构建一个系统,在该系统中,非官方客户端可以使用其范围内的所有访问权限是完全可以的,但是系统的安排方式是可以在所有客户端上正式使用更大。

通常,这是通过按用户访问的令牌完成的,而不是整个应用程序的一个令牌。对于您的API的典型用法,每个令牌的限制应该足够,但对于试图滥用它的人来说,限制是有限的。例如,每分钟100个呼叫可能足以支持典型的浏览,但是如果我想抓您,我将无法在该预算范围内有效地做到这一点。

总是会有一场军备竞赛-我可以通过创建许多机器人用户帐户来绕过限制。但是,如果您仅在注册流程中添加验证码,这是一个非常解决的问题,而这对真正的人来说是很小的一笔费用。当您进入这些场景时,一切都只是在便利与限制之间进行权衡。您将永远找不到完全防弹的东西,因此请专注于使其足够好,然后等到有人利用您了解漏洞所在。


8
接受这是最佳答案。我们决定采用的路由是使用到期时间较低的JWT令牌,并增加这些呼叫的速率限制。我们将在令牌中编码一些其他信息,以使后端知道更高的速率限制。由于这些令牌在后端安全地签名,因此欺骗不会有问题。有人仍然可以使用令牌,但是令牌将在几天后过期,因此维持任何一种机器人都将变得更加困难。
杰森·沃尔德里普

33

如果这导致您遇到问题,则将导致您的开发人员推定的生态系统出现问题(例如,当他们尝试开发替代UI时)。如果您确实在吃自己的狗食,请使API(和速率限制)适用于您的应用程序。这里有一些建议:

  • 请勿通过IP地址对限制进行评分。而是通过与用户相关联的东西(例如,他们的用户ID)来限制速率。在认证阶段应用速率限制。

  • 设计您的API,以便用户不需要连续调用它(例如,给出返回许多结果的列表调用,而不是每次都返回一个项目的重复调用)

  • 设计Web应用程序时要具有与开发人员生态系统相同的约束,即确保可以在合理的限制速率内进行设计。

  • 确保您的后端具有可伸缩性(最好是水平),这样您就不必在太低的级别上施加限制,这实际上会导致UI问题。

  • 确保您的节流能力有能力应付突发情况,并限制长期滥用。

  • 确保您的节流措施针对您要消除的滥用行为进行了明智的调整。例如,考虑排队或延迟轻度滥用者,而不是拒绝连接。大多数Web前端一次只能打开四个同时连接。如果您延迟打开第五个客户端的尝试,则只会碰到他们与Web客户端(两个Web客户端)同时使用CLI的情况。如果您延迟第n个API调用而没有失败而不是失败,最终用户将看到事情变慢而不是中断。如果您仅将这与仅排队N个API调用结合使用,那么您只会碰到并行处理大量API调用的人员,这可能不是您想要的行为-例如,同时进行100个API调用,那么通常要间隔一个小时在一小时内比100次连续API调用还差。

这没有回答您的问题吗?好吧,如果您确实需要执行所要执行的操作,请在身份验证阶段进行速率限制,并根据您的用户所属的组应用不同的速率限制。如果您使用一组凭据(由开发人员和质量检查团队使用),则您将获得更高的速率限制。但是您可以立即看到为什么这将不可避免地导致您看到生态系统中的问题,而开发人员和质量检查团队看不到这些问题。


11

购买您的产品。成为自己的付费客户。

“匿名访问我们的API每小时的API调用门槛非常低,而我们的付费客户每小时可以接受1000个或更多的调用。”

这也有助于从客户的角度测试系统。


1
显而易见的答案。这里没有作弊或伪造!
wizzwizz4 '16

9

不幸的是,没有完美的解决方案。

一般方法通常是提供 欺骗的客户端标识自己的方式(例如,标识符,版本和API密钥),客户端注册可用于限制访问的有关自身的信息(例如,客户端是给定IP地址范围内的服务器,因此,仅允许该范围内的调用者;例如,客户端是JavaScript,但仅传递给特定类别的浏览器,因此,仅允许访问指定某些用户代理字符串的HTTP请求;等等),然后使用机器学习/模式识别以检测可能是被欺骗的客户端的异常使用,然后拒绝来自这些被欺骗的客户端的流量(或与客户端确认这些使用确实不是来自合法客户端,替换其可欺骗的凭据,然后禁止使用较旧的客户端进行进一步的流量欺骗性凭证)。

通过使用多层密钥,可以使欺骗更加困难。例如,您给出了一个存在于服务器上的更长期的凭证(并且只能在有限的IP地址范围内使用),以进行API调用来记录有关客户端(例如,用户代理)的信息,并且返回寿命较短的客户端密钥,该密钥在JavaScript中联合在一起,可在客户端上用于客户端API请求。这也不是完美的(欺骗者可能发出相同的服务器调用以获取证书),但是如果将返回的API密钥包含在经过混淆(且经常更改)的JavaScript或HTML中,则将更加困难(这将使难度增加)以可靠地从响应中提取)。这也提供了一种更容易检测欺骗的方法。现在,客户端密钥已绑定到特定客户端(例如,


8

假设有问题的应用必须是公开开放的,那么您没有太多选择:

选择另一种方式来展示您的API的功能。例如,编写这样的应用程序并共享其源代码,但实际上不运行该代码。但是请确保已对其进行了充分的文档记录,以便任何人都可以部署它并看到它正在运行(可能会受到限制)。

您需要对您运行的应用进行重构,以避免客户端API请求,并且应将其渲染为更多服务器。您仍然可以放弃API,但不是以明显的方式—从服务器端对无限制API提出安全请求。

调整速率限制以允许您的应用正常运行,并进行性能优化以应对负载。

是的,首先要使核心API不受限制,并将其保留在专用网络中。节气门位于单独的公共访问层。


4

您是否可以单独使用UI和无限制API的实例,然后限制对来自组织的IP地址的访问?

例如,如果需要在实例之间共享数据,请将整个事情部署在公司防火墙后,并将应用程序与面向公众的实例连接到同一数据库。


4

您可以尝试生成唯一的会话ID,该ID绑定到特定的IP地址/用户和有限的生存时间。当用户下载您的应用程序前端时,JavaScript代码会将生成的会话ID注入JavaScript源代码中。会话ID会附加到您对API的每个请求中,并且速率限制会提高。

该ID不能简单地复制用于欺骗,因为它仅对单个IP地址,用户和有限的时间有效。因此,每当新用户想要使用它时,对手就必须调用您的页面并从JavaScript源或拦截Ajax请求中筛选出密钥。

另外的选择:

为您自己的应用程序设置代理并使用混淆功能。对代理的Ajax请求使用与真实API调用不同的名称,代理将它们转换回去。因此,您的应用程序不会调用getDocument您的真实API,但会调用getFELSUFDSKJE您的代理。代理会将此调用转换回getDocument并将其转发到实际的限速API。

您的实际API不会对代理的请求进行速率限制。

为了避免其他人将您的代理用于自己的应用程序,您每天都要更改混淆方案。混淆的呼叫名称可以在JavaScript源代码中自动生成并在代理中进行配置。

希望使用此功能的客户还需要跟上您不断变化的混淆才能使用代理。而且,您仍然可以使用引荐来源标头和类似标头进行记录,因此您可以使用代理找到人员。或在更改混淆方案时捕获它们。


3
  • 白名单源IP地址
  • 使用VPN,将VPN成员加入白名单
  • 如果您可以保护代理并且不关心MITM,则添加HTTP标头的代理解决方案或浏览器插件应该可以。攻击嗅探流量
  • 任何涉及机密的解决方案都可以通过每天轮换机密来减轻泄漏的影响

这些解决方案不适用于前端Web客户端。如果在后端访问API,则完美。
杰森·沃尔德里普

@jason它们都可以应用于前端
the8472 '16

2

设置多个帐户,并在每次请求时随机选择其中一个,或者每隔一个小时左右更改一次。这样,您就可以将负荷分配到各个n帐户,从而使您可以n限制上限几倍。

如果您试图找到其他这样做的用户(如果客户不允许这样做),请小心避免意外关机。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.