很多站长朋友们都不太清楚原生php实现csrf,今天小编就来给大家整理原生php实现csrf,希望对各位有所帮助,具体内容如下:
本文目录一览: 1、 PHP加了Token验证表单防止CSRF后还有必要做其它的防范吗 2、 php csrf攻击是通过浏览器还是直接攻击接口的 3、 如何用php获取某个页面中的input的csrf 4、 什么是 CSRF攻击? PHP加了Token验证表单防止CSRF后还有必要做其它的防范吗有必要,在安全防护方便不要心存侥幸,能想到的尽量一个也不要少,防患于未然!!
php csrf攻击是通过浏览器还是直接攻击接口的CSRF(Cross-site request forgery跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。
跨站通常指的是针对浏览器来说的,如果通过其他方式直接调接口,不存在跨站一说,HTTP协议本身并没有站这一概念。伪造请求必然会将所有的条件都设置正确(如referrer和csrf token),没有任何限制,对后端来说,请求必然是一个正确的。
如何用php获取某个页面中的input的csrf好问题,我这里有最好的答案。
composer包:
"symfony/css-selector": "3.1.*",
"symfony/dom-crawler": "3.1.*",
"guzzlehttp/guzzle": "6.2.*"
php代码
$body = (new \GuzzleHttp\Client)->get('')->getBody()->getContents();
$csrf = (new \Symfony\Component\DomCrawler\Crawler($body))->filter('#csrf_token')->attr('value');
var_dump($csrf);
另外,下一步应该是POST登录吧?
$res = (new \GuzzleHttp\Client)->post('', ['connect_timeout' => 10,
'form_params' => [
'csrf_token' => $csrf,
'email' => 'xxx',
'password' => 'xxx',
],
]);
// 登陆后拿到的html
$body = $res->getBody()->getContents();
$dom = new \Symfony\Component\DomCrawler\Crawler($body);
// 检查是否登录失败并抛出异常
if ($err_str = $dom->filter('.email-warn')->text()){
throw new \Exception($err_str);
}
补充
对了,忘了说了,csrfToken是和session相关的,如果你获取csrf和登录post用的不是一个sessionid的话,csrf是无效的。所以,获取csrf和post登录请共用这一个client以共享同一个cookie。
$client = new Client(['cookies'=>true]);
把上面代码里的(new \GuzzleHttp\Client)换成$client即可
什么是 CSRF攻击?,即在某个恶意站点的页面上,促使访问者请求你的网站的某个 URL(通常会用 POST 数据方式),从而达到改变服务器端数据的目的。这一类攻击依赖于你的网页中的表单,脆弱的表单很容易受到攻击。对于你网站中的访问者而言,可能会受到以下攻击: * 在你的网站之外记录受攻击者的日志(比如:Slashdot); * 修改受攻击者在你的网站的设置(比如:Google); * 修改你的硬件防火墙; * 使用受攻击者的登录信息在你的网站中发表评论或留言; * 将资金转移到另一个用户帐号中。 CSRF 攻击的典型是那些使用 cookie 记录登录信息的网站,但对于一些允许某个 IP 地址访问的页面(如内部网),这一类攻击也会奏效。 CSRF 攻击通常会使用到 JavaScript(但不仅限于 JavaScript)实现跨站点自动提交表单--表单数据可以隐藏,提交按钮可以伪装成链接或滚动条。 * 确定那些接受可改变服务器数据的 CGI 只接受 POST 参数,不接受 GET 参数,一些服务器端语言默认同时接受两种方式提交过来的参数; * 确定表单提交处理的是你自己的表单,可以使用一个隐藏字段中存放MD5字符串,此字符串是将登录 cookie 数据与服务器端存放的密钥进行 MD5 之后的结果,只有这个 MD5 字符串正确时才接受表单数据; * 另外还可以增加一个更为严格的方法:在表单中增加一个时间戳的隐藏字段,并将其包含到 hash 字符串中,如果时间戳超过某个时间,则认为表单已过期。当表单过期时,给出一个方法可以让用户重新提交表单,比如将用户之前填写的数据依旧放入表单中,但使用一个新的 hash 字符串。 一个PHP的表单例子,表单代码:<?php$key = y8s4Z7m2; //MD5加密密钥$time = time(); //当前时间 $hash = md5($time.$key); //hash 字符串?<form method="post" action="comment.php" <pYour name: <input type="text" name="person_name" /</p <pComment: /<textarea name="comment" rows="10" cols="60"</textarea</p <input type="hidden" name="time" value="<?php echo $time; ?" / <input type="hidden" name="hash" value="<?php echo $hash; ?" / <p<input type="submit" name="comment" value="Submit Comment" /</p</form表单提交之后的 comment.php 后台处理程序代码:<?php$key = y8s4Z7m2; //密钥,与上面的一致 $expire = 1800; //表单过期时间:半小时 $my_hash = md5($_POST[time].$key); //正确的 hash 字符串 if ($my_hash != $_POST[hash]) //hash 字符串不正确 die(非法表单提交。); if (time() - $_POST[time] $expire) { //表单已经过期,生成新的时间戳和 hash 字符串,显示表单让用户重新提交。(此处省略)//….}//表单验证通过,可以接受表单提交的数据,并进行其它操作。 //….?
关于原生php实现csrf的介绍到此就结束了,不知道本篇文章是否对您有帮助呢?如果你还想了解更多此类信息,记得收藏关注本站,我们会不定期更新哦。
查看更多关于原生php实现csrf 原生php开发的详细内容...