【问题标题】:Stop Spoofed Form Submissions停止欺骗性表单提交
【发布时间】:2012-03-01 10:57:02
【问题描述】:

我有一个关于停止提交欺骗性表单的问题。如果使用$_SERVER['HTTP_REFERER'] 我只允许提交来自我的网站的表单怎么办?那会有帮助吗?!谢谢!

【问题讨论】:

标签: php forms security


【解决方案1】:

建议是使用令牌。如果您使用任何流行的 MVC 架构,则无需担心,因为欺骗预防已得到照顾。但是,如果您像我一样使用自定义 MVC 架构,那么令牌就是一种方法。在您的 Database 类中,对于每个 CRUD(CREATE, READ, UPDATE AND DELETE) 函数,检查令牌。例如 令牌可以通过 md5 生成。

public function save(){
if(isset($_SESSION['token']){
//proceed with saving
}else{
//kill it,
die;
}
}

或者,您可以轻松地将您的 Web 应用程序与此跨站点请求伪造保护工具包集成。看看here

【讨论】:

    【解决方案2】:

    如果没有“欺骗”的定义,那就是空谈。

    有十几种不同的“欺骗”,每种都有不同的保护。

    最通用的解决方案是验证码。

    【讨论】:

      【解决方案3】:

      表单欺骗的主要问题是您无法控制客户端发送的内容。用户可以更改任何表单参数。因此,客户端在提交表单时发送的所有内容都需要经过验证和验证。

      这也意味着,您提供的要在表单中发送的参数越少,您需要验证和验证的就越少。尤其是那些预设且用户不会更改的参数(即隐藏的表单字段)如果不是真的需要,则不需要嵌入到表单中。相反,您可以将它们存储在 container in the session 中,并且仅通过隐藏字段引用此容器。如果这不是一个选项,请确保您至少可以通过使用MAC 唱出预设值来检测任何完整性缺陷。

      另一个问题是成功提交表单所需发送的表单参数是完全可预测的,因此攻击者可以重复发送有效的表单提交。如果您需要一个只能由您的服务器发出并在表单提交时验证的不可预测的参数,您可以验证表单提交是否被授予。

      一种解决方案是使用一个随机的一次性令牌,该令牌根据表单请求生成并存储在会话中,并作为隐藏输入字段放入表单中。然后在提交表单时检查是否提供了令牌以及它是否等于存储在会话中的令牌;如果它们相等,则从会话中删除令牌并处理表单,否则拒绝处理表单。

      坦率地说,这种机制并不完美,因为您仍然可以先请求表单,然后发送欺骗性表单数据。在那里您可以使用额外的验证码或其他阻止自动请求的机制。

      最好是使用上述所有措施的组合:

      • 在会话中创建一个具有足够随机标识符的表单容器;将该标识符作为隐藏输入字段放入表单中,以在表单提交时识别表单容器
      • 将任何预设参数存储在表单容器中,而不是表单中
      • 如果无法从表单中排除预设参数,则使用 MAC 验证其值(使用每个表单容器密钥)
      • 如果有可疑的重复表单请求/表单提交,请考虑另外使用验证码来防止自动请求

      此外,这些基于会话的表单容器还可以防止CSRF,因为它们的标识符对于攻击的第三方来说是不可预测的。

      【讨论】:

        【解决方案4】:

        欺骗 HTTP 标头非常容易,因此不应用于需要严格安全性的事情。通常使用的一种技术是在表单上的隐藏输入中同时发送加密的 cookie 和匹配的加密令牌。 cookie 应该是仅 HTTP cookie。在提交表单时,检查来自 cookie 的值和来自隐藏输入的值是否匹配。这将有助于防止跨站点请求伪造,因为无法从另一个站点成功向您的站点发出请求,因为它们将丢失 cookie(用于 MIM 攻击)或隐藏输入(欺骗形式)。当然,这取决于您确保您的网站在其他方面是安全的,这样他们就无法嗅探令牌以找出要提供的内容。

        这是一个关于如何在 ASP.NET MVC 中完成的很好的讨论,http://blog.stevensanderson.com/2008/09/01/prevent-cross-site-request-forgery-csrf-using-aspnet-mvcs-antiforgerytoken-helper/

        【讨论】:

          【解决方案5】:

          这会有所帮助,而且添加起来相当容易,但它不会阻止有针对性的攻击,毕竟你可以欺骗 HTTP_REFERER 标头。

          要记住的一点是,客户端不需要发送HTTP_REFERER,因此如果缺少标头,您可能仍希望允许提交。如果这是不可能的,那么检查HTTP_REFERER 不会帮助你。

          搜索 CAPTCHA“完全自动化的公共图灵测试以区分计算机和人类”,这就是您真正要找的。​​p>

          【讨论】:

            【解决方案6】:

            真的没用。读这个: http://shiflett.org/articles/form-spoofing

            【讨论】:

            • -1 仅提供链接不被视为 stackoverflow 上的答案。
            • 那么只有 cmets 中的链接更好?
            • 如果只是一个链接,那么 cmets 是发布它们的合适位置。评论不会征求赞成票。
            【解决方案7】:

            尝试像ReCaptcha 这样的验证码。您不仅可以防止垃圾邮件机器人向您的网站发送垃圾邮件,而且您还可以“授权”仅使用您的表单的人(至少在某种程度上 - 他们需要加载您的表单以获取验证码,然后发送回应)。

            【讨论】:

              【解决方案8】:

              Referer 很容易被欺骗,因此任何想要欺骗表单提交的攻击者也可以欺骗Referer 标头。另外,我不认为 Web 浏览器需要发送 Referer 标头,因此它可能会排除合法用户的表单帖子。

              【讨论】:

                【解决方案9】:

                引用者很容易被欺骗。

                您应该尽可能地验证表单以找出愚蠢的机器人,并可能使用服务器端 CAPTCHA。

                【讨论】:

                  【解决方案10】:

                  让我们明确一点:技术上不可能防止欺骗性的表单提交。一句话总结:

                  如果你的浏览器可以做到,那么每个人都可以做到。

                  【讨论】:

                  • 技术上是正确的,但可以在没有先前 GET 的情况下阻止表单提交。我不希望看到人们得出结论认为在一般情况下这是不可能的,因此未能采取必要措施来防止跨站请求伪造 (XSRF)。
                  • 我认为这取决于您建立的条件。如果会话经过身份验证、安全且相当短,cookie 已加密,使用了适当的技术(例如防伪令牌),则您可以在防止伪造表单方面设置很高的标准。
                  • 添加到 tvanfosson / David Conrad 的 cmets。如果您确保需要在数据库中更改任何敏感数据,尤其是密码/电子邮件之类的字段,要求用户输入密码并且不使用 $_GET / $_REQUEST 访问变量,这将有助于 XSRF和其他简单的欺骗/利用尝试。在 XSRF 方面,我认为不对帐户请求使用 $_GET / $_REQUEST 可以解决大部分问题。
                  • @BradFJacobs – CSRF 既不限于 GET 请求,也不限于单个请求。为带有 POST 请求的多步事务设置攻击只需要一点点努力。
                  【解决方案11】:

                  停下来?没有限制?可能。您的网站是否真的受到了数量惊人的欺骗性表单提交的打击,或者您只是先发制人?不要解决不存在的问题。

                  【讨论】:

                  • 安全问题一直存在。如果欺骗性的表单提交会成为问题,那么即使在第一次事件发生之前,也应该防范它们。
                  猜你喜欢
                  • 2017-01-12
                  • 2017-05-14
                  • 2017-01-08
                  • 1970-01-01
                  • 1970-01-01
                  • 2019-07-09
                  • 2014-01-24
                  • 2020-07-31
                  相关资源
                  最近更新 更多