保护Web API免受未经授权的应用程

时间:2012-10-11 15:44:47

标签: ajax web-services obfuscation

我正在开发一个使用大量AJAX与服务器通信的网页。反过来,服务器具有广泛的REST / JSON API,公开Web客户端调用的不同操作。

此网站由匿名用户和经过身份验证的用户使用。正如您所料,经过身份验证的用户发出的Web服务调用需要身份验证,因此可以防止未经授权的用户或应用程序。

但是,该网站有许多不需要身份验证的功能,其中一些功能使用匿名Web服务。我用来阻止外人调用此Web服务的唯一方法是使用CSRF token。我知道,CSRF令牌在这方面并不是很有用...有了一些时间,即使他们使用CSRF令牌,你也可以弄清楚如何使用Web服务。

当然,您可以使用CAPTCHA来阻止应用程序或机器人自动使用您的Web服务。但是,任何人都可以使用它。

另一方面,在客户端和服务器之间共享密钥是没用的。这是因为任何局外人都有能力从网页源代码中读取它。

我想让这些Web服务难以调用,因为它们可以用于任何第三方应用程序。除了使用CSRF令牌,你会做什么?这听起来有点愚蠢,但嘿,也许这很愚蠢,我只是在浪费时间。

注意:鉴于此应用程序使用浏览器而不是“可执行文件”作为客户端,this question与讨论无关。我不能在服务器和客户端之间使用秘密(至少我不知道)

5 个答案:

答案 0 :(得分:1)

您可能遇到更容易问题,而不是链接问题中描述的问题,因为您不需要向用户分发二进制文件。即使您的应用程序是开源的,HMAC /签名密钥(在该答案的“请求签名”部分中)也可以通过环境/配置设置进行控制。

总结:

  1. 密钥实际上并不是在客户端和服务器之间发送的。相反,它用于签署请求
  2. 请确保请求包含一些唯一/随机元素(您的CSRF密钥可能已足够),以便对相同API数据的两个请求不相同。
  3. 使用密钥对请求进行签名,并将签名附加到请求中。您链接到PHP问题但不清楚您使用的语言是什么。在.Net中,我会使用HMAC类,例如HMACSHA256
  4. 在API服务器端使用相同的HMAC对象来验证请求是否使用相同的密钥签名。

答案 1 :(得分:1)

也许您可以使用计数器来跟踪对话。只有服务器和客户端才能预测会话中的下一次迭代。这样,我认为,您可以阻止第三方应用程序冒充某人(虽然只是一个想法)。

一开始,他们开始谈论某些迭代(例如i=0)。

  • 每次客户端请求某些内容时,计数器在服务器端和客户端(i=i+some_number)都会增加一些数字。

  • 并且,在几分钟没有沟通之后,他们都知道他们必须重置柜台(i=0)。

答案 2 :(得分:1)

这只是基于RSA概念的想法,也是在您的系统上放置欺诈检测。授权用户的风险很小,但他们也可以尝试匿名调用您的Web服务。

对于UN授权用户:对于每个Web服务调用,使用RSA生成令牌,该令牌在一段时间后会更改(可配置为30分钟)。这样可以最小化代码预测。到目前为止我还没有听说过RSA碰撞。将此令牌发送回用户以进行浏览器会话。为了进一步提高安全性,我们可能希望使用RSA令牌附加会话ID。由于会话ID是唯一的,因此新的匿名调用将需要新的会话ID。

可以使用审核机制跟踪呼叫。此外,每个Web服务还可以有不同的RSA设置。欺诈检测算法如何发挥作用本身就是一个挑战。

对于授权用户: 应使用Header块通过其IP地址跟踪每个用户。可以应用RSA令牌原则。

解决方案非常模糊但值得考虑。

答案 3 :(得分:1)

我会采取一些步骤。

  • 在网站上强制https。自动将任何传入的http请求重定向到https请求(RequireHttps属性对此很方便)
  • 每个页面需要(安全地,因此https)向客户端发送一次性使用令牌,以用于页面。客户端上运行的脚本可以将其保存在页面内存中。任何回来的请求都会发送散列和放大器。盐渍响应,以及nonce盐。服务器可以使用保存的标记+ salt和hash重复这些步骤以确认请求。 (很像explunit上面的回答) (值得注意的是,来自客户端的安全请求未通过用户帐户进行身份验证,只是通过整页发送的令牌。)
  • 一次性定义可以是会话或页面加载,具体取决于您的安全性与便利性偏好。代币应该很长并且很快过期以挫败攻击者。

SSL +哈希(令牌+随机数)应该足以满足您的需求。

答案 4 :(得分:1)

这很有趣。以下是一个疯狂的建议。请记住,你的问题也同样疯狂。

您的网站一旦通过浏览器打开,就会产生一个长轮询连接(Comet编程)。这将在浏览器和服务器之间创建一个唯一的会话。当你的JS正在进行ajax调用时,通过长轮询线程向服务器发送一些令牌(每次唯一令牌)。让AJAX也发送相同的令牌。在服务器上,获取AJAX令牌并检查在长轮询会话中是否有类似的令牌。如果是,请完成请求。任何程序员都可以打破这个。但是,这并不容易。机会是免费的人甚至不会看到这些第二段彗星代码。您可以以不易检测或理解的方式实现彗星代码。当他们呼叫您的服务时,发送“服务不可用”消息。他们会感到困惑。还要制作彗星代码https。

您还可以检查长轮询线程的打开时间。如果会话刚刚打开并且您立即收到ajax呼叫,则可以认为它是第三方呼叫。这取决于你的网站流量。如果在页面加载1秒后发生了Ajax调用,则可以在服务器端检查该模式。

任何为您的公共API编码的人都会进行1到2次他们甚至不知道的秘密检查,即使他们知道,他们可能会因为他们必须做的所有额外编码而气馁。