手机版

PHP开发中csrf攻击的简单演示与防范

时间:2021-09-05 来源:互联网 编辑:宝哥软件园 浏览:

Csrf攻击,即跨站点请求伪造跨站点(域名)请求伪造,其中伪造意味着伪造。网上有很多关于CSRF的介绍,比如一位前辈的文章详细解释了csrf的攻击方式。参考本文,csrf攻击的实现依赖于一个简单的事实,即我们在使用浏览器浏览网页时,通常会打开几个浏览器选项卡(或窗口)。如果我们登录站点a,如果站点a通过cookie跟踪用户的对话,那么,用户登录站点a后,站点a会在用户的客户端设置cookie。如果站点A有一个网址被站点B知道的页面siteA-page.php(url资源),并且这个页面的地址以某种方式嵌入到站点B的一个页面siteB-page.php中,如果用户在维护站点A会话的同时打开站点B的siteB-page.php,只要siteB-page.php页面能够触发这个URL地址(请求站点A的URL资源),就可以实现csrf攻击。

上面的解释很尴尬。让我们举一个简单的例子来演示一下。

1、背景和正常请求流程

站点A的域名是html5.yang.com,它有一个/get-update.php?Uid=uidusername=username地址,可以看到这个地址可以通过get方法传递一些参数。如果这个页面的逻辑是:它通过判断uid是否合法来更新username,那么这个页面的脚本如下:

?Php//这里为了简单起见,从data.json中取出数据,而不是请求database $ str=file _ get _ contents(' data . JSON ');$data=json_decode($str,true);//检查cookie和请求更改的uid。实际上,检查数据库中的用户是否为空($ _ cookie ['uid']) | |空($ _ get ['uid']) | | $ _ get ['uid']!=$data['id']?Die(“非法用户”):“”;//检查用户名参数$ data ['username']=空($ _ get ['username'])?Die('用户名不能为空'): $ _ GET[' username '];//update data $ data[' username ']=$ _ get[' username '];if(file _ put _ contents(' data . JSON ',JSON _ encode($ data))){ echo ' username已更改为{ $ data[' username ']} br ';} else {die('更新失败');}通常情况下,此页面的链接会放在站点a下,例如站点a的csrfdemo.php页面,登录站点a后,用户可以点击此链接发送请求。例如,站点a有一个包含以下链接的页面脚本:

?Php//这里,使用一个data.json文件来保存用户数据并模拟数据库中的数据。//首先将data.json中的数据初始化为{'ID' :101,' username' :' jack'},注意这句话只执行一次,然后注释掉//file _ put _ contents ('data.$ data=JSON _ decode(file _ get _ contents(' data . JSON '),true);//这里,为了简单起见,省略了用户验证if ($ data ['username'])的过程{//set cookie setcookie ('uid ',$ data ['id'],0);Echo '登录成功,{ $ data[' username ']} br ';}?a href=' http://html 5 . yang.com/csrfdemo/get-update . PHP?uid=101 username=JSON ' rel=' external nofollow '将用户名更新为json /a,以如下方式加载此页面:

点击页面中的链接,进入get-update.php页面:

以上是正常的请求流程。让我们看看站点B是如何实现csrf攻击的。

2.csrf攻击的最简单实现

网站B的域名是test.yang.com,里面有一页csrf.php。只要用户在维护站点A会话的同时打开这个页面,站点B就可以实现csrf攻击。至于它为什么会打开.其实这种场景在我们浏览网页的时候是很常见的。比如我写这个博客的时候写了觉得在csrf某个地方听不懂,然后百度出来了很多结果。如果有一个叫csrf百科知识的网站,这个网站对csrf的介绍非常详细和权威,那么我大概会点进去看看,但是这个网站其实是一个钓鱼网站,正在某个地方访问。好了,言归正传,我们来看看csrf.php的剧本代码:

?php?img src=' http :http://html 5 . yang.com/csrfdemo/get-update . PHP?Uid=101username=jsonp '可以看到上面的代码中没有php代码,只有一个img标签,img标签的src是更新站点a用户名的链接,但是用户名改为jsonp,访问站点b的csrf.php页面:

让我们访问下一个网站的csrfdemo.php页面:

您可以看到用户名被更改为jsonp。

简单分析一下:网站b的csrf.php在html中使用了img标签。我们都知道img标签有一个src属性,属性值指向要加载的图片的地址。加载页面时,加载图片相当于向src指向的地址发起http请求。只要将图片的地址修改为脚本地址,最简单的csrf攻击自然就实现了。这样,csrf很容易实现,但每个人都是“绅士”,谁无事可做,谁就闲着没事干这种“脏”事。但是,害之心不可少,防之心不可少。让我们来看看如何简单地防范这种最简单的csrf攻击。

3、简单的预防措施

其实预防措施比较简单。站点A可以判断get-update.php脚本中请求头的来源。如果来源不是站点A,则可以截断请求。在下面添加一些get-update.php的代码:

?Php//如果(!空($ _ SERVER[' HTTP _ REFER ']){ if(parse _ URL($ _ SERVER[' HTTP _ REFER '],PHP_URL_HOST)!='html5.yang.com') {//您可以设置http错误代码或指向无害的url地址//标头(' HTTP/1.1 404未找到');//标头(' HTTP/1.1 403 forbiden ');header(' location : http://html 5 . yang.com/fav icon . ico ');//这里需要注意exit(),否则脚本接下来会执行exit();} } $ str=file _ get _ contents(' data . JSON ');//代码省略了,但是一切都会好吗?如果http请求头是伪造的呢?a站点升级防御,B站点可以同时升级攻击。csrf是通过curl请求实现的。修改乙站点的csrf.php代码如下:

?PHP $ URL=' http://html 5 . yang.com/csrfdemo/get-update . PHP?uid=101 username=jsonp ';$ refer=' http://html 5 . yang.com/';//curl方法启动csrf攻击$ ch=curl _ init();curl_setopt($ch,CURLOPT_URL,$ URL);//设置refer curl _ setopt($ ch,curl opt _ referer,$ refer);//你需要在这里带饼干,因为A站点的get-update.php已经判定了烹饪。Curl _ setopt ($ ch,Curl opt _ cookie,' uid=101 ');curl _ exec($ ch);curl _ close($ ch);img src=' http :http://html 5 . yang.com/csrfdemo/get-update . PHP?Uid=101username=jsonp ',这也可以达到csrf攻击的目的。那么没有更好的方法来预防吗?4.摘要

让我们回到问题的开始。站点A通过cookiess跟踪用户会话,cookie存储重要的用户信息uid。get-update.php脚本通过判断用户的cookies是否正确来决定是否更改用户信息。通过cookies跟踪会话和控制业务逻辑似乎不安全。最严重的一点是,get-update.php通过get request修改用户信息,这是一大禁忌。所以a站点可以升级防御:用session代替cookie跟踪用户会话信息,重写修改用户信息的逻辑,只允许post方法请求用户信息。站点B也可以升级攻击:curl可以构造post请求,劫持会话等。不过这些我还没研究过,以后再说吧。

版权声明:PHP开发中csrf攻击的简单演示与防范是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。

相关文章推荐