如何保护REST服务中的“公共”部分免受垃圾邮件的侵扰?

24

我有一个REST服务,它非常完整并将被用于iOS应用程序。它使用Ruby/Sinatra构建,但我认为这并不重要。

我正在使用基本的HTTP身份验证加上SSL来保护各个端点,这部分工作非常出色。

问题是:如何防止垃圾邮件发送者等呼叫未受到HTTP基本身份验证保护的REST服务部分?

例如:用户注册

假设REST调用是(POST) ... /register_account,在请求主体中传递JSON对象。

由于明显的原因,此调用不能期望用户名/密码与用户帐户关联。

想法:

1)该应用程序拥有自己的“用户名”/密码,并且某些调用将检查应用程序凭据。 问题:对设备进行root操作等可能会暴露这些凭据。

2)该应用程序通过HTTP头传递秘密令牌到REST服务以进行这些调用。 问题:与(1)相同

是否有常用的技术可以防止此类垃圾邮件呼叫?我考虑可能将iPhone的设备ID引入其中,但尚未确定明确的方法。

谢谢

4个回答

8
虽然应用程序特定代码是防止垃圾邮件的第一道防线,但您仍应在任何涉及到的服务上实施一些速率限制。
例如,如果您在REST服务上使用会话,您可以轻松地对单个会话处理的调用数量进行速率限制。该会话不必进行身份验证,只用于标识单个客户端在发出请求时。如果他们尝试连接而没有打开会话,则只需简单地重定向回所请求的服务即可,几乎所有web框架或堆栈都内置了此功能。
您还可以基于其他属性进行速率限制,例如IP或用户代理指纹,但这些方法不如基于会话的方法可靠。

我将使用这个宝石:https://github.com/datagraph/rack-throttle 来进行速率限制。我将对其进行子类化,以便客户端标识符是设备ID + IP地址的组合。还将保留应用程序凭据的想法。 - Riaz

6
通常使用的一种方法是API密钥,与您上面描述的密钥令牌相同。您可以将其硬编码到应用程序中,并使其难以被反向工程(隐藏它,在应用程序内的不同位置构建它等)。您是正确的,坚定的攻击者将能够恢复密钥(如果您的应用程序可以这样做,拥有对您的应用程序访问权限的其他人也可以)...但是您可以使它更加困难,从而希望不值得花费时间和精力去做。
您还可以考虑部署相互认证的SSL,以便您的服务器仅接受来自您的应用程序的传入连接,并且您的应用程序仅与您的服务器通信。
以下是高级方法。创建自签名服务器SSL证书并在Web服务器上部署。然后在应用程序中创建一个自签名客户端并将其部署为资源。配置服务器要求客户端SSL身份验证,并仅接受您生成的客户端证书。配置客户端使用该客户端证书标识自己,并仅接受您在服务器上安装的一个服务器端证书作为其中的一部分。
如果除您的应用程序之外的其他人/事物尝试连接到您的服务器,则不会创建SSL连接,因为服务器将拒绝未提供应用程序中包含的客户端证书的传入SSL连接。

9
您可以花费数天时间编写逻辑来“隐藏”API密钥并在应用程序中分散它的部分,但最终这个应用程序会发起请求,检查网络日志就能看到带有密钥本身的URL。在Web应用程序中这特别容易,只需在任何浏览器的开发工具中检查“网络”选项卡即可,但在移动设备上也很容易实现。 - vir us

1
这确实很古老,但你可以做一些事情。我会创建一个基于时间的秘密令牌。一些在几秒钟内过期的东西,你可以随请求一起发送。由于你的iOS应用程序源代码不是公开的,所以只有你知道如何保守秘密。你需要确保应用程序和服务器之间的时间同步。你可以从移动应用程序向服务器发送时间并计算偏移量(如果有)。这将防止除你的应用程序之外的任何其他东西在身份验证之前与你的API通信。
将秘密基于某些仅手机独有且只有你知道的内容。这种独特性也必须在服务器端知道。

-5
你可以使用request.ip跟踪IP地址,并编写一些相关的逻辑。

错误的;有很多人在NAT后面,因此大量不相关的请求可以来自单个IP。 - mbq
2
返回翻译文本:true。但我可以将移动/平板设备ID和IP组合成哈希,生成一个唯一的令牌与之比较。 - Riaz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接