什么是CSRF?

你可以理解为:攻击者盗用你的身份,以你的名义发送恶意请求。它被称为“跨站请求伪造”。它能干的事情有很多:当你打开某个网站时,你另一个已经打开的购物网站已经完成支付;以你名义发送邮件,发评论;网络蠕虫;虚拟货币转账…

CSRF攻击流程

  • 用户登录A网站(受信任的)
  • A网站确认身份
  • 在A中访问B网站链接(危险的)
  • B网站拿到A中的 cookie 后直接向其服务器发送请求

这看似简单,其中却有一些值得注意的问题。比如:
1. B网站向A服务器发送请求,是否会引起跨域问题?

不会。因为并不是所有的请求都会引起跨域。如 HTML 中的 <img><script> 标签就不会。而且它们的 src 中放的链接其实就是一次 get请求。

著名的jsonp就是用了 script 允许跨域的特性实现的

而且,通过 form 表单发送POST请求的方式也会被用来做攻击。笔者曾看过这样的一段代码:

<? phpsession_start();if(isset($_POST['toBankId']) && isset($_POST['money'])){buy_stocks($_POST['toBankId'],$_POST['money']);}
?>
# 服务端为了防止由img导致的get请求轻易地获取数据,改为只接收POST请求,但
<body onload="steal()"><iframe name="steal" display="none"><form method="POST" name="transfer" action="http://www.myBank.com/Transfer.php" target="steal"><input type="hidden" name="toBankId" value="11" /><input type="hidden" name="money" value="1000" /></form></iframe><script>function steal(){iframe=document.frames["steal"];iframe.document.submit("transfer");}</script>
</body>

隐藏的 iframe 表单提交 —— 如果一个 form 表单的 target 值等于 iframename 值。那么这个表单数据会在 iframe 中提交,进而跳转。此时,如果这个 iframe 还设置了 display:none; 那么在页面看来并没有什么“不适”。

2. 攻击者能拿到cookie吗?

不能。CSRF攻击是攻击者利用 cookie 欺骗服务器,但攻击者并不能知道 cookie 的内容。而且,对于服务器返回的数据(结果),由于浏览器同源的限制,攻击者也无法解析。他所做的也就是给服务器发送请求,以执行请求中所描述的命令,在服务器端直接修改数据的值。而非窃取数据!

3. 上面说要csrf生效,基本需满足两点:1、登录受信任网站A,并在本地生成Cookie;2、在不登出A的情况下,访问危险网站B。那如果我不满足以上两个条件中的一个,我就不会受到CSRF的攻击?

理论上确实如此,但你不能保证以下情况不会发生:

  1. 你不能保证你登录了一个网站后,不再打开一个tab页面并访问另外的网站。
  2. 你不能保证你关闭浏览器了后,你本地的Cookie立刻过期,你上次的会话已经结束。(事实上,关闭浏览器不能结束一个会话,但大多数人都会错误的认为关闭浏览器就等于退出登录/结束会话了…)
  3. 所谓的攻击网站,可能是一个存在其他漏洞的可信任的经常被人访问的网站。

CSRF的防御

1. 前端token,后端校验
CSRF 攻击之所以能够成功,是因为攻击者可以伪造用户的请求,该请求中所有的用户验证信息都是存在于 cookie 中,因此攻击者可以在不知道这些验证信息的情况下直接利用用户自己的 cookie 来通过安全验证。
要抵御 CSRF,关键在于在请求中放入攻击者所不能伪造或者拿不到的信息;或者可以在 HTTP 请求中以参数的形式加入一个随机产生的 token,并将token保存到本地(cookie中),然后在服务器端建立一个拦截器来验证这个 token,如果请求中没有 token 或者 token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。

简单来说就是:在服务端生成一个随机的token并保存起来并且跟随请求带给前端。而前端拿到后保存到一个隐藏域中,跟随每次请求带到后端:

// 后端代码,这里以node(koa)为例
let csrfToken=parseInt(Math.random()*9999999,10);ctx.cookies.set('csrfToken',csrfToken);
<input calss="csrfToken" type="hidden" name="csrfToken" value="" />
<script>document.querySelector(".csrfToken").value=getMyCookie('csrfToken');
function getMyCookie(key){var val = "";// 对cookie操作var cookies = document.cookie;cookies = cookies.replace(/\s/,"");var cookie_array = cookies.split(";");for(i=0;i<cookie_array.length;i++){// name=mxcvar cookie = cookie_array[i];var array = cookie.split("=");if(array[0]==key){val = array[1];}}return val;
}</script>

在每次请求的回调中都生成一个新的值,然后在下一次请求过来时校验(cookie中的值和参数中的值相同,并且和后端生成的值也相等)。

这样就要求必须同时知道参数中的token和cookie中的token,才能成功发动攻击

2. same-site属性
cookie自带的有一个sami-site属性,可以控制第三方网站是否携带cookies:

  • Strict:任何请求都不允许带cookies
  • Lax(默认):允许比如链接可以携带cookies
  • None

写法:

// 以koa为例
ctx.cookies.set('cid',    //第一个参数,key'hello world',   //第二个参数,value{   //第三个参数,cookie设置domain: 'localhost',  // 写cookie所在的域名path: '/index',       // 写cookie所在的路径maxAge: 10 * 60 * 1000, // cookie有效时长(http1.1)expires: new Date('2017-02-15'),  // cookie失效时间(http1.0)httpOnly: false,  // 是否只用于http请求中获取sameSite: Strict,overwrite: false  // 是否允许重写}
)

但是这种方式目前还存在兼容性问题,而且受支持程度并不好。

3. 访问来源
其实简单的还有一种方式:通过 document.referrer 判断当前页面是从哪个链接过来的。通常也会随header携带到服务端,服务端也可以获取到:req.headers.referrer
但是referrer可以被伪造,这种方式非常不安全。


当然,还可以通过如Spring中的某些设置或者一些方式去达到防御的目的。笔者在查阅资料途中发现了一篇文章,手段比较偏后端的。感兴趣的可以点我移步这里查看。

Web安全:跨站点攻击csrf相关推荐

  1. 跨站点请求伪造_十大常见web漏洞——跨站点请求伪造(CSRF)

    CSRF介绍 什么是CSRF呢?我们直接看例子. https://mp.toutiao.com/profile_v3/graphic/preview?do=delete&pgc_id=6829 ...

  2. 总结 XSS 与 CSRF 两种跨站攻击

    在那个年代,大家一般用拼接字符串的方式来构造动态 SQL 语句创建应用,于是 SQL 注入成了很流行的攻击方式.在这个年代, 参数化查询 [1] 已经成了普遍用法,我们已经离 SQL 注入很远了.但是 ...

  3. XSS与CSRF两种跨站攻击比较

    XSS:跨站脚本(Cross-site scripting) CSRF:跨站请求伪造(Cross-site request forgery) 在那个年代,大家一般用拼接字符串的方式来构造动态SQL 语 ...

  4. XSS和CSRF两种跨站攻击比较

    以下是我从一个大佬那转过来的 觉得写得非常非常好哈哈哈 忍不住想转载 可惜好像从博客园直接转过来转不过来 这是原文链接 XSS:跨站脚本(Cross-site scripting) CSRF:跨站请求 ...

  5. 总结XSS与CSRF两种跨站攻击

    XSS:跨站脚本(Cross-site scripting),实际应是"CSS",但由于和层叠样式表CSS名称冲突,故改为"XSS" CSRF:跨站请求伪造(C ...

  6. 【burpsuite安全练兵场-客户端12】跨站点请求伪造CSRF-12个实验(全)

    前言: 介绍: 博主:网络安全领域狂热爱好者(承诺在CSDN永久无偿分享文章). 殊荣:CSDN网络安全领域优质创作者,2022年双十一业务安全保卫战-某厂第一名,某厂特邀数字业务安全研究员,edus ...

  7. 如何修复会话固定漏洞_PHP安全漏洞:会话劫持,跨站点脚本,SQL注入以及如何修复它们...

    如何修复会话固定漏洞 PHP中的安全性 (Security in PHP) When writing PHP code it is very important to keep the followi ...

  8. 常见的Web攻击方式:SQL注入、XSS跨站脚本攻击、CSRF跨站点请求伪造

    常见的Web攻击有SQL注入.XSS跨站脚本攻击.跨站点请求伪造共三类,下面分别简单介绍. 1 SQL注入 1.1 原理 SQL注入就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字 ...

  9. 我要学ASP.NET MVC 3.0(十三): MVC 3.0 防止跨站点请求伪造 (CSRF) 攻击

    我要学ASP.NET MVC 3.0(十三): MVC 3.0 防止跨站点请求伪造 (CSRF) 攻击 概述      众所周知,ASP.Net MVC程序在浏览器运行时产生了标准的Html标签,包括 ...

最新文章

  1. 如何扫描和修复 Linux 磁盘错误
  2. go 定义一个结构体并赋初始值_Go中必须谈论的四个迷点
  3. 安装 PyCharm
  4. java实现dvd租赁系统_Java编写汽车租赁系统
  5. adb 的原理以及它总重启等问题详解
  6. 无线路由器的配置实例
  7. Google Analytics使用说明
  8. 让beanshell和bashshell一起工作
  9. comparator接口_8000字长文让你彻底了解 Java 8 的 Lambda、函数式接口、Stream 用法和原理
  10. POJ 2763 Housewife Wind【LCA_RMQ+树状数组】
  11. 生于俄罗斯的 Web 服务器王者 Nginx,现宣布俄罗斯禁止贡献
  12. AWT_Swing_JPasswordField密码框(Java)
  13. EasyRecovery恢复数据的具体步骤是什么
  14. date java format_java-DateFormat
  15. dojo省份地市级联之地市封装类(二)
  16. 谷歌电子市场第4天总结
  17. android10 谷歌服务框架,google服务框架下载官方版
  18. 微软Azure动手实验营4月课程预告
  19. 如何实现点击收藏,图标变色;再次点击,取消收藏,图标变回原来的颜色,且能把已收藏的项发送请求给后端
  20. Celery 全面学习笔记

热门文章

  1. java interface 函数_Java8 函数式接口(Functional Interface),有且仅有一个抽象方法...
  2. HTML代码转成字符串数组
  3. 刷脸支付技术成熟能够为安全问题保驾护航
  4. mStar 6A648 双 WiFi
  5. Boston Dog
  6. 浙大计算机能保研交大清华吗,太牛了吧?寝室4个男生分别保研到清华、北大、浙大和上海交大...
  7. usaco Barn Repair 解题报告
  8. vue echarts中改变canvas长和宽 自适应
  9. 2020-3-17课堂笔记
  10. ETL工具Informatica开发流程 综合应用 电信通话计费系统开发项目案例10