csrf攻防-攻击&防护代码演示
Posted liuxiaodi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了csrf攻防-攻击&防护代码演示相关的知识,希望对你有一定的参考价值。
前言
CSRF(Cross-site request forgery,跨站请求伪造,恶意网站伪造身份冒充你向目标服务器发送请求。CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账......造成的问题包括:个人隐私泄露以及财产安全。
攻击原理
csrf攻击通过利用浏览器机制:发送请求的域相同时,浏览器会自动携带相同cookie.具体原理做法如下:
客户刚登录完目标网站,目标网站下发了信任凭证cookie.客户没有执行登出操作,在目标网站仍然开启的情况下,进入了恶意网站.恶意网站内,攻击行为是向目标网站的服务器发起请求,恶意网站会把请求域名设置的和目标网站cookie的Domain相同.利用同一个浏览器下发送请求时,请求域名和domain相同,会携带该domain属于的cookie这一点,恶意网站请求可以携带上目标网站的cookie.目标网站的服务器接受到请求后,会认为这是用户的操作,就会去执行操作内容
如下请求,是恶意网站的常见代码,img或a向目标服务器发送请求,由于请求域(xiaodidi.com)和目标网站域相同,请求时就会自动携带上xiaodidi.com域的相关cookie
<img src="http://www.xiaodidi.com....>
<a href="http://www.xiaodidi.com....>
攻击代码举例
恶意网站只需要发送如下一个请求给银行,银行那边就会给这个id的用户扣款1000
<img src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>
解决crsf方法
csrf攻击利用了浏览器在请求域相同时,会携带相同cookie,达到攻击目的.从这个角度想,我们防止csrf攻击可以,我们可以额外添加一个token身份验证,因为token不是cookie,恶意网站没有办法拿到token放到请求中.服务端接受请求时去判断cookie和token是否正确,双管齐下.
具体到项目中流程是:
- 第一次登录的时候,服务端生成token,通过响应头返回
- 客户端拿到响应头的token,存储在localstorage中(一定不能在cookie中)
- 客户端设置全局的请求配置,给每个请求头都加上token
- 服务端拿到前端请求的token,解密token对比验证身份
实现代码:
ps:用nodejs做服务端
1.第一次登录的时候,服务端node用插件jsonwebtoken生成token,在express的res.set方法中将token放入响应头中,返回给客户端
下载jsonwebtoken,生成token,
//生成token
const jwt = require(‘jsonwebtoken‘);
let token = jwt.sign(username, privateKey, { algorithm: ‘RS256‘ });
res.set方法中将token放入响应头中
res.set(‘X-ACCESS-TOKEN‘, token) //添加token, 向header里面添加一个自定义的字段, req.session.username = user["username"]; res.send({ code: 1, username: user["username"], message: "用户登录成功" })
2.客户端在ajax请求的success回调中拿到响应头的token,存储在localstorage中
const post = (url, data) => { return new Promise((resolve, reject) => { $.ajax({ url, type: ‘POST‘, data, //xhr内部包含响应头内容,具体可查看ajax文档 success: (res, status, xhr) => { res.status = status; res.xhr = xhr; resolve(res) }, error: (err) => { reject(err); } }) }) } //rs是resolve()方法中的内容,这里省略了.then //jquery.ajax内部参数xhr中通过getResponseHeader可以获取header内的具体内容 let token = rs.xhr.getResponseHeader("x-access-token") localStorage.setItem(‘token‘, token);
3.客户端设置全局的请求配置,给每个请求头都加上token
$.ajaxSetup({
//全局发送请求前配置 beforeSend(xhr, setting) { let token = localStorage.getItem(‘token‘);
xhr.setRequestHeader(‘x-access-token‘, token); }, complete(xhr, setting) { if (xhr.responseJSON.code === 401) { alert(xhr.responseJSON.message) router.go(‘/index‘) } } })
4.服务端拿到前端请求的token,解密token对比验证身份,不合法的身份返回401
const jwt = require(‘jsonwebtoken‘) function auth(req, res, next) { if (req.session.username) { try { let token = req.get(‘x-access-token‘); //对称 let rs = jwt.verify(token, ‘lagouadmin‘) if (rs === req.session.username) { next(); } else { res.send({ code: 401, message: "非法访问" }) } } catch (error) { log.error(req.session.username + " 登录失败 " + error.message) res.send({ code: 401, message: "非法访问" }) } } else { res.send({ code: 401, message: "非法访问" }) } } module.exports = auth;
以上就是一个csrf防守生成token的代码实现流程
以上是关于csrf攻防-攻击&防护代码演示的主要内容,如果未能解决你的问题,请参考以下文章