Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何为检查请求源提供更高的安全性_Php_Security_Csrf - Fatal编程技术网

Php 如何为检查请求源提供更高的安全性

Php 如何为检查请求源提供更高的安全性,php,security,csrf,Php,Security,Csrf,我正在开发一个PHPWeb应用程序,我想为应用程序提供更多的安全性,这样就不会有人轻易破坏该功能 关于我的问题的简要说明: 在一个模块中,有一个阶段我检查请求的来源(该请求来自哪里) 目前,我使用的是HTTP\u referer变量(在php中提供)。我正在用一个特定的URL(例如)检查这个变量值。如果确实存在匹配,那么只有我要求采取进一步行动 我对上述方法有点困惑,我应该使用HTTP\U Referer还是检查IP地址(如果来自任何特定IP地址,则请求有效) 我还想知道提供安全性的更好方法 有

我正在开发一个PHPWeb应用程序,我想为应用程序提供更多的安全性,这样就不会有人轻易破坏该功能

关于我的问题的简要说明: 在一个模块中,有一个阶段我检查请求的来源(该请求来自哪里)

目前,我使用的是
HTTP\u referer
变量(在php中提供)。我正在用一个特定的URL(例如)检查这个变量值。如果确实存在匹配,那么只有我要求采取进一步行动

我对上述方法有点困惑,我应该使用HTTP\U Referer还是检查IP地址(如果来自任何特定IP地址,则请求有效)

我还想知道提供安全性的更好方法

有没有人有想法请分享

提前感谢

网络安全第1课: 永远不要相信用户的输入。当我说永远,我的意思是永远在PHP中包含HTTP_refere变量,该变量很容易被HTTP头破坏(来源:)

检查源代码的一个可能的解决方案是使用表单令牌(csrf保护):但这也不安全,而且只有在您自己的源代码中才可能

一个简单的CSRF(跨站点请求伪造)保护示例:(因此是简单的。有关更安全/健壮的解决方案,请参阅Rook的答案)

1) 在表单页面中,创建某种令牌并将其放入会话和隐藏的表单字段中:

<?php
    session_start();
    $csrfToken = md5(uniqid(mt_rand(),true)); // Token generation updated, as suggested by The Rook. Thanks!

    $_SESSION['csrfToken'] = $token;
?>
<form action="formHandler.php">
   <input type="hidden" name="csrfKey" value="<?php echo $csrfToken ?>" />
</form>


检查CSRF的
HTTP\u referer
是一种有效的保护形式。虽然在您的浏览器上欺骗此HTTP头很简单,但在另一个人的浏览器上使用CSRF欺骗它是不可能的,因为它是

根据国土安全部的数据,我发现了,并且是有史以来最危险的1000个漏洞中的一个。摩托罗拉通过一个referer检查修补了这个漏洞,在嵌入式网络硬件上看到这种保护方法是很常见的,因为内存不足

一种更常见、更安全的方法是在
$\u会话
变量中存储一个变量,并为每个敏感请求检查该变量。一种简单的方法是对所有敏感请求(如更改密码)使用
POST
,并确保此加密nonce对php头文件中的所有POST有效,如果无效,则
unset($\u POST)。此方法之所以有效,是因为尽管攻击者可以强制您的浏览器发送GET/POST请求,但他无法查看响应,并且无法读取伪造请求所需的令牌。此令牌可以通过XSS获得,因此请确保您可以


生成csrf令牌的一个好方法是
md5(uniqid(mt_rand(),true))这应该足以阻止CSRF。md5()用于隐藏盐是如何生成的。请记住,当前时间是而不是一个秘密,攻击者确切知道CSRF请求产生的时间,并且可以缩小会话创建的时间范围。您必须假设攻击者可以进行许多猜测,实际上,这很容易通过向页面写入一组iframe来实现

Treur说得对,但我仍想澄清一些事情,并为您提供一些参考资料来源。正如Treur所说,永远不要相信用户输入的数据,这些数据包括浏览器发送的所有标题

您所描述的是一种典型的跨站点请求伪造攻击。检查referer报头不是针对CSRF攻击的有效保护,因为根据RFC2616(),referer报头是可选的,因此浏览器随时可以忽略它。如果您使用的是SSL,那么浏览器总是会忽略referer头。其次,它是一个用户定义的值,因此不应被信任

针对CSRF攻击的建议防护措施是使用同步令牌模式。这意味着您应该创建一个秘密令牌,该令牌作为隐藏字段嵌入到表单中。发布表单时,您将验证密钥令牌是否存在且有效。创建安全令牌有多种策略。我将描述一种创建令牌的方法:

对于应用程序中的每个操作,为它们创建唯一的操作名称。例如,“删除用户”、“添加用户”或“保存用户配置文件”。假设您描述的表单具有动作名称“foobar”。将操作名称与用户的会话id和秘密值连接起来


$stringValue=“foobar”。“秘密价值”。会话_id();

要创建安全令牌,请创建连接字符串的散列,可以使用sha1创建散列。要降低暴力攻击的风险,请在哈希中使用较大的密钥,例如sha 512


$secretToken=hash(“sha5125”,$stringValue);

在表单的隐藏字段中设置此令牌。提交表单时,重新创建令牌并验证它是否与表单中提交的令牌匹配。此令牌对一个用户会话有效。有人可能会说,存在一个机会窗口,攻击者可以重用令牌,因为它不是在每次请求时重新生成的。然而,有了适当的会话管理策略,这不应该是一个真正的问题

正如我所说,适当的会话管理是必要的。这意味着您不应该让会话持续太长时间。尤其是漏洞将撤销任何CSRF保护措施,因为攻击者随后控制用户会话,因此可以“预测”秘密令牌

以下是我建议您通读的几个链接:


HTTP\u REFERER与请求源无关。您最好检查IP地址,而不是感谢大家的快速响应,@Treur:我的有效测试用例是:我正在使用简单的表单方法(即post)发布一些值,如“年龄”、“id”、“描述”、“备注”。我
<?php
   session_start();
   if($_POST['csrfKey'] != $_SESSION['csrfKey']) {
      die("Unauthorized source!");
   }
?>