【问题标题】:How to block external http requests? (securing AJAX calls)如何阻止外部http请求? (保护 AJAX 调用)
【发布时间】:2012-05-25 03:52:38
【问题描述】:

我想使用 post 来更新数据库并且不希望人们手动执行它,即它应该只能通过客户端中的 AJAX 来实现。在这种情况下是否可以使用一些众所周知的加密技巧?

假设我正在发出一个 GET 请求,将一个新用户插入我的数据库site.com/adduser/<userid>。有人可能会通过发出虚假请求来过度填充我的数据库。

【问题讨论】:

标签: ajax security http ring


【解决方案1】:

我真的不需要限制对服务器的访问(尽管那会很棒),我正在寻找一种加密技巧,它可以让服务器知道什么时候来自应用程序而不是由使用嗅探令牌的用户。

你不能这样做。这几乎是客户端/服务器应用程序的基本问题之一。这就是它不起作用的原因:假设您有一种方法可以让您的客户端应用程序向服务器验证自身 - 无论是秘密密码还是其他方法。应用程序需要的信息必须可由应用程序访问(密码隐藏在某处或其他地方)。但是因为它在用户的计算机上运行,​​这意味着他们也可以访问这些信息:他们所需要的只是查看源代码、二进制文件或应用程序与服务器之间的网络流量,最终他们会弄清楚您的应用程序验证和复制它的机制。也许他们甚至会复制它。也许他们会编写一个聪明的 hack 来让你的应用程序完成繁重的工作(你总是可以向应用程序发送虚假的用户输入)。但无论如何,他们已经获得了所需的所有信息,没有办法阻止他们拥有这些信息,也不会阻止您的应用拥有它。

【讨论】:

  • 这是我在各种重复问题上看到的最好的解释。你应该把它添加到stackoverflow.com/questions/1756591/… 这是这个问题最老的骗子。
  • 你说得对,@IMSoP,该线程的答案有很多无能。我稍微调整了我的回复,因为 OP 真正需要的是指向身份验证的方向。
【解决方案2】:

可以实现。
每当您呈现应该发出此类请求的页面时。生成一个随机令牌并将其存储在会话(用于经过身份验证的用户)或数据库中(以防公开允许此请求)。
而不是调用site.com/adduser/<userid> 调用site.com/adduser/<userid>/<token>
每当您收到此类请求时,令牌是否有效(来自会话或数据库)
如果令牌正确,则处理请求并从会话/数据库中删除使用的令牌
如果令牌不正确,则拒绝请求。

【讨论】:

    【解决方案3】:

    在这种情况下无法避免伪造请求,因为客户端浏览器已经拥有发出请求所需的一切;恶意用户只需进行一些调试即可弄清楚如何向您的后端发出任意请求,甚至可能使用您自己的代码使其更容易。你不需要“加密技巧”,你只需要混淆,这只会让伪造有点不方便,但仍然不是不可能的。

    【讨论】:

    • 我担心会是这样。如果有人有任何混淆技巧可以建议,我会全力以赴。
    【解决方案4】:

    这是一些授权问题:只有授权请求才会导致创建新用户。所以当收到这样的请求时,你的服务器需要检查它是否来自一个被授权创建新用户的客户端。

    现在的主要问题是如何决定授权什么请求。在大多数情况下,这是通过用户角色和/或一些票务系统完成的。使用用户角色,您将需要解决其他问题,例如用户识别和用户身份验证。但如果这个问题已经解决,您可以轻松地将用户映射到像 Alice 是管理员Bob 是普通用户 这样的角色,并且只有管理员有权创建新用户。

    【讨论】:

      【解决方案5】:

      解决方案是在 ajax 请求中添加粗线。此外,您应该查看基本身份验证,这不会是唯一的保护者。您可以从您的 ajax 页面中使用这些代码获取收入

      Ajax 调用

      function callit()
      {
       if(window.XMLHttpRequest){xmlhttp=new XMLHttpRequest();}else{xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");}
       xmlhttp.onreadystatechange=function(){if(xmlhttp.readyState==4&&xmlhttp.status==200){document.getElementById('alp').innerHTML=xmlhttp.responseText;}}
       xmlhttp.open("get", "call.asp", true);
       **xmlhttp.setRequestHeader("X-Requested-With","XMLHttpRequest");**
       xmlhttp.send();
      }
      

      PHP/ASP 请求的页面回答

      ASP

      If Request.ServerVariables("HTTP_X-Requested-With") = "XMLHttpRequest" Then
       'Do stuff
      Else
       'Kill it
      End If
      

      PHP

      if( isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && ( $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' ) )
      {
       //Do stuff
      } else {
       //Kill it
      }
      

      【讨论】:

      • 感谢您的努力,但这只是其他人提到的标题检查。它不够安全,因为用户可以伪造标题。
      【解决方案6】:

      这与 CSRF 存在相同的问题 - 解决方案是相同的:在 AJAX 请求中使用一个令牌,该令牌您以前存储在 eslewhere 中(或者可以重新生成,例如通过使用 sessin id 作为密钥加密参数) . Chriss Shiflett 对此有一些明智的说明,还有一个 OWASP project 用于使用 PHP 检测 CSRF

      【讨论】:

      • 这和 CSRF 的问题不太一样。在 CSRF 中,这是一个身份问题,但我担心用户自己可能会滥用自己的登录凭据、自己的会话令牌,并使用自己的帐户人为地填充数据库。
      • 鉴于不可能将服务器的访问限制为仅您的 ajax API,它与 CSRF 完全相同
      • 我真的不需要限制对服务器的访问(虽然那会很棒),我正在寻找一种加密技巧,它可以让服务器知道什么时候来自应用程序并且不是由用户使用嗅探令牌伪造的。
      • 为什么不使用只在短期内有效的令牌? (但足以完成您的 AJAX 请求)。您可以使用在客户端和服务器中实现的秘密算法基于服务器的时间生成代码。客户端将此代码添加到其请求中,服务器将检查该代码是否仍然有效。类似于 IPsec 避免复制攻击的“技巧”。如果该号码无效,则该请求将被丢弃。请注意,这只是一个想法,我没有工作代码!
      【解决方案7】:

      Prevent Direct Access To File Called By ajax Function 似乎解决了这个问题。

      您可以(在其他解决方案中,我敢肯定)...

      • 使用会话管理(登录创建会话);
      • 向客户端发送一个唯一密钥,该密钥需要在过期之前返回(不能 可重复使用,不能储存以备日后使用);
      • 和/或在链接的答案中设置标题。

      但如果人们足够努力,任何事情都可能被欺骗。唯一完全安全的系统是任何人都无法访问的系统。

      【讨论】:

        【解决方案8】:

        它像任何其他网页一样工作:登录身份验证,检查引荐来源。

        【讨论】:

        • 你能澄清一下吗?您是说服务器应用程序将知道谁发出请求并且它可能只识别 AJAX 请求?
        • 请参阅:stackoverflow.com/questions/7127686/… 会话身份验证由您决定。您可以为客户端提供一个密钥,该密钥会随每个请求传回。
        • 我真的找不到任何安全的解决方案。我考虑过发送客户端身份验证,但随后客户端自己可以嗅探标头并为自己重用密钥。必须有一个更强大的解决方案,因为所有网络应用都需要这个。
        • 依赖referer不是一个好主意。 OTOH,您无法使用 AJAX 做任何用户无法通过其他方式复制的操作。
        • 伪造推荐人相当容易。
        猜你喜欢
        • 2011-05-08
        • 1970-01-01
        • 2011-02-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多