【问题标题】:Securing a javascript client with hmac使用 hmac 保护 javascript 客户端
【发布时间】:2010-11-23 23:14:03
【问题描述】:

我正在研究保护我正在开发的 javascript 应用程序的方法。该应用程序是一个使用 APE(Ajax Push Engine)作为后端的聊天客户端。

目前,任何人都可以访问该页面并向 APE 服务器发出 GET/POST 请求。我只想为注册用户提供聊天客户端,并且我想确保只接受他们的请求。我可以使用 PHP 的用户名/密码身份验证来为用户提供页面。但是一旦他们有了页面,有什么可以阻止他们修改 javascript 或让它落入坏人之手?

这种保护客户端/服务器应用程序的方法看起来很有前途:http://abhinavsingh.com/blog/2009/12/how-to-add-content-verification-using-hmac-in-php/

我有另一个消息来源说这是 javascript 客户端的理想选择,因为它不依赖于发送私钥。但这怎么可能呢?根据上面的教程,客户端需要提供私钥。这似乎不太安全,因为任何拥有 javascript 的人现在都拥有该用户的私钥。据我了解,它会像这样工作:

  1. 用户使用用户名和密码登录
  2. PHP 验证用户名和密码,查找用户的私钥并将其插入到 javascript 中
  3. Javascript 提供一个签名(使用私钥),以及所有 APE 请求的公钥
  4. APE 将计算出的签名与接收到的签名进行比较,并决定是否处理请求。

如果 javascript 应用程序需要知道私钥,这如何保证安全?

感谢您的帮助!

【问题讨论】:

  • 嗨 Walderman,从这里看到了帖子的引用者,所以让我借此机会解释一下博客文章中解释的工作。解释的方法更多的是一种流验证方法,即如果您想确保调用的 ajax/javascript/api 确实是通过您的应用程序控制流设计的。如果服务器端缺少 crumb 信息或无效(由于超时或损坏),您只需忽略呼叫....希望它清除工作。解释的方法不要求您在客户端发送任何私钥..

标签: php javascript hmac ajax-push


【解决方案1】:

答案:从技术上讲,您是 cannot prevent the user from modifying the JavaScript。所以不要担心,因为你对此无能为力。

但是,您需要防止的攻击是Cross-Site Request Forgery (CSRF)。不同域上的恶意脚本能够使用浏览器存储的 cookie 自动向您的域提交表单。为了解决这个问题,您需要在 AJAX 请求发送的实际数据中包含一个身份验证令牌(它应该是足够随机的,与用户名或密码无关,并且在聊天客户端所在的 HTML 页面中发送)(浏览器不会自动填写)。

【讨论】:

  • 这是否类似于 OAuth 所做的事情,服务器进行身份验证,然后在 x 时间内向客户端提供访问令牌?
  • @Walderman:它不必像 OAuth 那样复杂。我所说的只是将授权令牌(例如在 cookie 中使用的令牌)放在 HTML 页面或服务器的第一个 AJAX 响应中,并让服务器检查所有后续响应,确保发送令牌(使用方法其他而不是cookie)。
【解决方案2】:

如果 javascript 应用程序需要知道私钥,这如何保证安全?

为什么不呢?这是用户自己的私钥,所以如果他愿意把它给别人,那是他的问题。这与提供您的密码然后说其他人可以访问您的帐户没有什么不同。

如果您稍微考虑一下,您会意识到您不需要实施公钥加密、HMAC 或类似的东西。只要通信通道本身是安全的(比如使用 HTTPS),您就可以使用正常的基于会话的身份验证。

【讨论】:

  • 即使接收ajax请求的APE服务器被HTTPS保护,任何人仍然可以点击0.ape.mydomain.com发送数据。目前,他们甚至不需要经过身份验证就可以做到这一点。 APE 服务器不知道 PHP 会话,因此需要其他方式来验证客户端的身份。
  • @Walderman:在这种情况下,让 PHP 向客户端发送一个随机生成的临时密钥,并让客户端将其与每个请求一起发送到 APE。您需要将此密钥存储在数据库中,以便 PHP 和 APE 都可以访问它。
【解决方案3】:

HMAC 身份验证更适合第三方要连接的 API。通过将 cookie 写入客户端的浏览器表明它们已通过身份验证,您的应用似乎会得到更好的服务。然后对于每个 ajax 请求,您可以检查该 cookie。

编辑:我收回关于 HMAC 更好地为第三方 API 服务的说法。传统上,使用 HMAC,每个用户都会获得自己的私钥。我认为这对您的应用程序不是必需的。您可能只需保留一个主私钥并为每个用户提供一个唯一的“公钥”密钥(我称之为公钥,但实际上用户永远不会知道密钥)。当用户登录时,我会写两个 cookie。一个是用户的公钥 + 加密时间戳的组合,另一个是说明时间戳是什么的密钥。然后在服务器端,您可以验证加密密钥并检查时间戳是否在给定阈值内(例如 10-30 分钟,以防他们在您的应用程序上闲置)。如果它们被验证,更新加密的密钥和时间戳,冲洗并重复。

【讨论】:

  • 谢谢。也许我遗漏了一些东西,但是如何阻止不受欢迎的用户发现此 cookie,然后使用它来发送请求?
  • 一个人可能会看到 cookie,但除非他们在您的域中,否则他们将无法将相同的 cookie 写入您的域。如果您担心它,您可以使用 HMAC 并编写公钥和使用私钥加密的时间戳的组合。这样,私钥永​​远不会通过 javascript 或 cookie 公开。
  • 似乎这里的共识是我应该设置某种 cookie/token/key 并与每个 ajax 请求一起发送。是否有使用 cookie 而不是仅在查询字符串中包含值的情况?似乎使用 cookie 可能更晦涩难懂,但如果客户端禁用 cookie,那么我的应用程序将无法运行。
  • 如果您将它包含在查询字符串中,您会遇到同样的问题,任何人都可以看到该变量并将帖子或获取请求推送到您的服务器。使用这些值在您的域上编写 cookie 要困难得多。但最终归结为安全性与可用性以及了解您的客户群以了解他们是否愿意打开 cookie。在我的 Web 开发经验中,我没有遇到太多客户在浏览器上禁用 cookie 的问题。
  • 据我了解,cookies也有同样的问题,只是你需要稍微下定决心。难道任何人都不能使用正确的工具读取浏览器的所有 cookie,然后创建一个带有适当标头的 http 请求吗?当然,攻击者需要能够看到 cookie(即通过与合法客户端共享计算机)
猜你喜欢
  • 1970-01-01
  • 2012-06-19
  • 2020-05-14
  • 1970-01-01
  • 2013-11-29
  • 2017-06-29
  • 1970-01-01
  • 2015-10-29
  • 2013-08-08
相关资源
最近更新 更多