【问题标题】:How to protect a private REST API in an AJAX app如何保护 AJAX 应用程序中的私有 REST API
【发布时间】:2012-01-18 23:07:00
【问题描述】:

我知道发布了许多类似的问题,但没有一个是指用户可以访问代码的 HTML/javascript 应用程序。

我有一个用 nodejs 编写的私有 REST API。它是私有的,因为它的唯一目的是为我的 HTML5 客户端应用程序(Chrome 应用程序和 Adob​​e Air 应用程序)提供服务。因此,API 密钥不是一个好的解决方案,因为任何用户都可以看到 javascript 代码。

我想避免机器人在我的服务器上创建帐户并消耗我的资源。

有什么办法可以实现吗?

【问题讨论】:

  • 我不确定是否有任何答案满足您的问题。请分享您如何解决您描述的问题。我正在构建可用于未注册用户的基于 REST + AJAX 的 Web 应用程序。和你一样,我想保护资源免受机器人攻击。
  • 从逻辑上讲,如果从任何人都可以查看源和/或监视发送到服务器的数据的网页调用 API,则实际上没有办法使 API 真正私有。要捕获机器人,您可以使用 Captcha 等常用技巧,但最终您需要后端支持(WAF、快速自动缩放等)来应对自动 DDOS 类型攻击的可能性。只要您尽早检测到可能的 DDOS 攻击(在建立数据库连接等之前),就与处理试图下载页面的机器人没有什么不同。

标签: javascript security api rest node.js


【解决方案1】:

API 密钥是一个不错的解决方案,尤其是当您需要限制 API 密钥的请求来源时;请考虑仅当原始 Web 请求来自授权来源(例如您的私有域)时才应接受 API 密钥。如果 Web 请求来自未经授权的域,您可以简单地拒绝处理该请求。

您可以通过使用专门的编码方案来提高此机制的安全性,例如基于散列的消息身份验证代码 (HMAC)。以下资源清楚地解释了这种机制:

http://cloud.dzone.com/news/using-api-keys-effectively

【讨论】:

  • 同样重要的是要注意 API 密钥解决方案适用于包括 Google Maps、Flickr、Facebook 等在内的许多其他 API。诀窍在于实现。
  • 我无法控制我的用户来自哪里,它是一个公共应用程序。 Google 地图、Flickr 等使用 API 密钥,但我不确定他们是否担心谁使用这些密钥。我认为我可以复制和使用任何谷歌地图密钥(没有尝试过)。
  • 您不能简单地复制 Google Maps API 密钥并在另一个域中使用它,因为 Google Maps API 将每个生成的 API 密钥与特定的域类(即 mydomain.com)和每个请求联系起来根据引用 URL 和 API 密钥中编码的其他信息检查传入的内容。同样,典型的编码机制是 HMAC。否则 API 密钥将毫无用处。
  • 推荐人可能会被欺骗,所以我不相信它的有效性:cyberciti.biz/faq/…
【解决方案2】:

您要做的是使用相互验证的 SSL,这样您的服务器将只接受来自您的应用的传入连接,而您的应用只会与您的服务器通信。

这是高级方法。创建一个自签名服务器 SSL 证书并部署在您的 Web 服务器上。如果您使用的是 Android,您可以使用 Android SDK 中包含的 keytool 来实现此目的;如果您使用的是另一个应用程序平台,它们也有类似的工具。然后创建一个自签名客户端并将其部署在您的应用程序中作为资源包含在您的应用程序中的自定义密钥库中(keytool 也会生成它)。将服务器配置为要求客户端 SSL 身份验证并仅接受您生成的客户端证书。将客户端配置为使用该客户端证书来标识自己,并且只接受您在服务器上安装的一个服务器端证书。

如果您的应用程序以外的某人/某物尝试连接到您的服务器,则不会创建 SSL 连接,因为服务器将拒绝未提供您应用程序中包含的客户端证书的传入 SSL 连接。

一步一步的回答比这里保证的要长得多。我建议分阶段执行此操作,因为网络上有关于如何在 Android 中处理自签名 SSL 证书的资源(我不熟悉如何在其他移动平台上执行此操作),包括服务器端和客户端。在我由 O'Reilly 出版的《Android 平台的应用程序安全性》一书中也有完整的演练。

【讨论】:

  • 我的网络应用是纯 javascript 和 HTML,而不是 android
  • 而且这种方法仍然有效。在您的应用程序的 Web 服务器和您想要与之通信的任何客户端之间强制执行相互身份验证 SSL。
  • 我怎样才能为标准的网络浏览器做到这一点?比方说谷歌浏览器。
  • 您需要生成客户端证书并将其作为身份证书加载到浏览器的密钥库中。你如何做到这一点取决于浏览器。
  • 但我不能问我的用户。我不认为他们会知道该怎么做。
猜你喜欢
  • 2011-04-23
  • 2013-12-26
  • 2017-08-09
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-25
相关资源
最近更新 更多