【问题标题】:Stop Post Data From Different Domain PHP停止发布来自不同域 PHP 的数据
【发布时间】:2009-07-01 16:38:11
【问题描述】:

我是 PHP 的初学者。

我正在尝试做的是阻止来自另一个网页的发布数据。

我遇到的问题是,假设有人复制了我的表单并将其粘贴到他们的网站上。我希望能够阻止 Post Data 在我的电子邮件表单上运行脚本。

我该怎么做?如果我不够清楚,请告诉我。

我的 PHP 联系表单在带有条件语句的页面上运行。即,如果数据签出,则提交。

【问题讨论】:

  • 我也试过在 PHP 中检查 URL,但后来我发现这是一个业余错误。
  • 好的。我查看了你们给我的东西,我想到了一个不同的想法,使用你们给我的东西......如果我随机一组字符 => 转换为一个变量,将其发布为隐藏值所以它每次都会改变,并在我的脚本运行时检查它?
  • 又是业余的错误......对不起。
  • 谢谢大家!没有大家的帮助是不可能做到的!

标签: php forms post


【解决方案1】:

“接受的答案”存在安全漏洞。相反,您应该使用更安全的方法。一个简单的例子:

第 1 步:禁用生成表单的页面 (.php) 的框架,在顶部添加:

header('X-Frame-Options: Deny');

第 2 步:(重要部分!): 为了避免 XSS 和 3rd 方漏洞,您应该创建一个可过期的验证。 例如:

  • ASP.NET 内置表单使用动态输入 csrf(示例值:gtlkjh29f9ewduh024cfvefb)
  • WordPress 内置表单使用动态输入 nonce(示例值:340297658942346)

因此,如果您使用的是自定义平台,该平台没有内置的临时令牌验证方法,请实施您的方法。一个简单的概念:

<?php  
$secret_key      = 'fjd3vkuw#KURefg';  //change this
$encrypted_value = Cryptor::encrypt( time(), $_SERVER['REMOTE_ADDR'] . $secret_key);
?>
<form>
...
...
<input value="<?php echo $encrypted_value;?>" name="temp_random" type="hidden"  />
</form>

(密码是here)

提交时,检查:

if(!empty($_POST)){

   // If REFERRER is empty, or it's NOT YOUR HOST, then STOP it
   if( !isset($_SERVER['HTTP_REFERRER']) || parse_url($_SERVER['HTTP_REFERRER'])['host'] != $_SERVER['HTTP_HOST'] ){
       exit("Not allowed - Unknown host request! ");
   }

   // Now, check if valid
   if (   Cryptor::decrypt(  $_POST['temp_random'], $_SERVER['REMOTE_ADDR'] . $secret_key) < time() - 60* 15 ) {
       exit("Not allowed - invalid attempt! ");
   }

   ...........................................
   ... Now, you can execute your code here ...
   ...........................................

}

【讨论】:

  • 当然,这是最准确的答案。
【解决方案2】:

你试图阻止CSRF - Cross-Site Request Forgery。 Jeff himself 有一篇关于此的博客文章。

真正的 XSRF 预防需要三个部分:

  • 隐藏的输入字段,以防止有人抢走表单并将其嵌入
  • 在生成的表单的 epsilon 内进行时间检查,否则有人可以生成一次有效的表单并使用令牌(取决于执行/存储方式)
  • Cookie:这是为了防止恶意服务器伪装成客户端并执行中间人攻击

【讨论】:

    【解决方案3】:

    $_SERVER['HTTP_Referrer'] 会很好,但它不可靠。您可以使用 MD5 的隐藏表单字段,然后在另一边检查它。

    【讨论】:

    • 如果我确实将数字随机化并将其作为隐藏值发布,但它会发生变化。
    • 哦,等等,他们可以删除隐藏的值并使其工作....哈哈。 dangit,就在我认为我掌握了 PHP 的时候。
    • 我想我终于弄明白了,我用了session_start,在表单显示的时候做了一个sessions变量,然后检查变量是否设置为提交!
    • 你在使用服务器端会话吗?
    • 你不能相信 HTTP_Referrer,它很容易被欺骗。
    【解决方案4】:

    形式:

    <?
    $password = "mypass"; //change to something only you know
    $hash = md5($password . $_SERVER['REMOTE_ADDR']);
    echo "<input type=\"hidden\" name=\"iphash\" value=\"$hash\"/>";
    ?>
    

    当你检查时:

    $password = "mypass"; //same as above
    if ($_POST['iphash'] == md5($password . $_SERVER['REMOTE_ADDR'])) {
        //fine
    }
    else {
        //error
    }
    

    【讨论】:

    • REMOTE_ADDR 可能被欺骗,所以如果有 MITM 攻击,这将证明毫无价值。同样,在我提出一个请求后,我可以通过简单地复制哈希轻松地做更多的事情,这会使这个变得毫无价值,哈希的“独特”部分需要更加“独特”,这就是我选择使用时间的原因() 女巫提供当前纪元时间。
    • “攻击者”不是客户端,而是另一台为他的客户端提供表单页面的服务器。
    • 不管怎样,它仍然可以很容易地发生。
    • 我相信对 Unkwntech 的回答同样的 AJAX-Remote-Loading 评论也适用于此。真正的 XSRF 保护需要 cookie、隐藏的表单输入和 epsilon 时间考虑因素。
    【解决方案5】:

    如果您正在寻找一种快速而简单的方法,您可以查看 REFERER 标头。

    如果您确实想确保表单是从您的站点获取的,则应在每次加载表单时生成一个令牌并将其附加到会话中。一个简单的方法是这样的:

    $_SESSION['formToken'] = sha1(microtime());
    

    那么你的表单可以有一个隐藏的输入:

    <input type="hidden" name="token" value='<?=$_SESSION['formToken'];?>' />
    

    您可以在决定是否处理表单数据时进行检查。

    【讨论】:

    • 你还需要检查 $_POST 中的令牌吗?为什么不检查 $_SESSION 值是否仍然设置?
    【解决方案6】:

    每个用户都进行注册,然后获得一个登录 ID。

    以下是防止 CSRF 的算法:-

    1) $login_id = user login id (converted to a numeric id using mysql)
    2) $a_secret_key = $_SERVER['UNIQUE_ID'];
    3) $remote_addr = $_SERVER['REMOTE_ADDR'];
    4) Request Date and Time -> A unique reference key -> $refkey
    5) $_SESSION['secretkey'] = $_SERVER['UNIQUE_ID'];
    

    在将数据传输到另一个页面时,结合上述1到4创建一个json文件。

    然后

    echo "<input type=\"hidden\" name=\"refkey\" value=\"$refkey\"/>";
    

    在接收端:-

    接收者页面应该检查是否

    1) any json file with $refkey exists at server?
    
    2) If $refkey exists, then check $login_id, $a_secret_key and $remote_addr exists and are correct.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-16
      • 2012-08-31
      • 2021-07-03
      相关资源
      最近更新 更多