【问题标题】:How to prevent submitting form from localhost to server如何防止从本地主机提交表单到服务器
【发布时间】:2012-01-02 19:52:55
【问题描述】:

我用谷歌搜索了两天,但找不到任何描述以下问题的内容:

假设我在“www.example.com”上有以下表单:

<form action="formProcessor.htm" method="post">
  <input name="field1" value="abc" />
  <input name="field2" value="123" />
  <input name="field3" value="etc" type="hidden" />
  <input value="Submit" type="submit" />
</form>

我担心的是:如果有人创建一个模拟此表单的本地文件,手动填写所有值,然后将其提交到“www.example.com/formProcessor”怎么办?

问题 #1:有什么办法可以防止这种情况发生吗?

问题 #2:这算不算所谓的 CSRF?

我知道您可以尝试验证 REFERRER,但我也知道这很容易伪造(只需查找“修改标头”FF 插件)。

如果这是一个基本问题,请耐心等待,我对网站安全还很陌生。

标记

【问题讨论】:

    标签: forms security csrf


    【解决方案1】:

    在表单页面 (php) 上使用以下/类似内容:

    session_start();
    if (empty($_SESSION['formkey'])) {
    $_SESSION['formkey'] = time() . "-" . getmypid() . "-" . rand(0, mt_getrandmax());
    }
    

    在表单中设置一个隐藏的表单域:

    <input type="hidden" name="formkey" value="<?php echo $_SESSION['formkey']; ?>" />
    

    然后在处理/处理程序页面上:

    if ($_SESSION['formkey'] !== $_POST['formkey']) {
    header("Location: formpage.php?blankfields");
    exit();
    }
    

    我尝试从远程服务器发帖,但它按预期失败。 讨厌这些垃圾邮件机器人,不确定他们通过发送垃圾邮件表单到底想达到什么目的?

    【讨论】:

      【解决方案2】:

      是的,那是Cross-site Request Forgery

      您可以通过创建一次性密钥并将其存储在表单中的隐藏输入元素中来防止它发生,如下所示:

      <?php
      
      $_SESSION['formkey'] = md5(rand() . time() . $_SERVER['REMOTE_ADDR']);
      
      ...
      
      <input type="hidden" name="formkey" value="$_SESSION['formkey']" />
      
      ?>
      

      在提交时,您检查提交的密钥是否与您存储在会话中的密钥匹配。如果是,则处理该表单,否则拒绝该请求。

      攻击者(或通过攻击者站点访问的无辜访问者)将不知道密钥,因此无法提交表单。

      只有来自您网站的访问者(您在每个表单上重新生成并设置正确的密钥)才能提交。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-12-12
        • 2013-02-25
        • 2019-02-18
        • 1970-01-01
        • 2013-04-16
        • 2011-01-06
        • 2012-05-26
        • 1970-01-01
        相关资源
        最近更新 更多