- CSRF
- Cross Site Request Forgy
跨站请求伪造
需要条件
用户登录 A 网站
A 网站确认身份
B 网站页面向 A 网站发起请求 (带 A 网站身份)
CRSF 攻击危害
利用用户登录态 --- 盗取用户资金 (转账, 消费)
用户不知情 --- 冒充用户发帖背锅
完成业务请求 --- 损坏网站名誉
...
CSRF 攻击防御
过程:
B 网站向 A 网站请求
带 A 网站 Cookies
不访问 A 网站的前端
referer 为 B 网站 (这里的 referer 为为数不多的错误单词)
禁止第三方网站带 Cookies, 为 Cookies 设置 Same-site 属性
koa 设置方式
- ctx.cookies.set("userId", user.id, {
- httpOnly: false,
- sameSite: "strict"
- });
这种方法较好但是, 有些浏览器不支持, 但将来应该会的
不访问 A 网站的前端
在前端页面加入验证消息
验证码
安装第三方插件生成验证码
运行
- NPM install ccap --save
- captcha.captcha = async function(ctx, next) {
- var ccap = require("ccap");
- var capt = ccap();
- var data = capt.get();
- captcha.setCache(ctx.cookies.get("userId"), data[0]);
- ctx.body = data[1];
- };
- // 设置
- captcha.setCache = function(uid, data) {
- console.log(uid, dtat);
- cache[uid] = data;
- };
- // 验证
- capthcha.validCache = function(uid, dtat) {
- return cache[uid] === data;
- };
下面调用上面
- console.log(data.captcha);
- // 没有验证码
- if (!data.captch) {
- throw new Erroe("验证码错误");
- }
- // 验证码不匹配
- var captcha = require("../tools/captcha");
- var result = captcha.validCache(ctx.cookies.get("userID"), data.captcha);
- console.log("result", result);
- if (!result) {
- throw new error("验证码错误");
- }
不访问 A 网站的前端
在前端页面加入验证消息
token
验证码有时是会影响用户体验的, 所以就有了 taken, 一般为隐藏的文本框
- var csrfToken = parseInt(Math.random() * 99999999, 10);
- ctx.cookies.set("csrfToken", csrfToken);
- // 渲染时
- ctx.render("post", {
- post, comments, csrfToken
- });
验证
- if (!data.crsfToken) {
- throw new Error("CSRF Token 为空");
- }
- if (data.csrfToken !== ctx.cookies.get("csrfToken")) {
- throw new Erroe("CSRF Token 错误");
- }
Ajax 做法
html 头部
<meta http-equiv="X-UA-Compatible" content="csrfToken" name="csrf_token" />
referer 为 B 网站
验证 referer
禁止来自第三方网站的请求
- var referer = ctx.request.header.referer;
- // console.log(ctx.request.header, referer);
- if(!^https?:\/\/loaclhost/.test(referer)){
- // if(referer.indexOf('localhost')===-1)// 验证不全面, 所以要采用上面的做法
- throw new Error('非法请求')
- }
来源: http://www.bubuko.com/infodetail-3399938.html