CSRF,也称 XSRF,即跨站请求伪造攻击,与 XSS 相似,但与 XSS 相比更难防范,是一种广泛存在于网站中的安全漏洞,经常与 XSS 一起配合攻击。
CSRF 原理
攻击者通过盗用用户身份悄悄发送一个请求,或执行某些恶意操作。
CSRF 漏洞产生的主要原因:
1、请求所有的参数均可确定
2、请求的审核不严格,如:只验证了 Cookie
关于 CSRF 的执行过程,这里引用自 hyddd 大佬画的图:
我们知道,当我们使用 img 等标签时,通过设置标签的 src 等属性引入外部资源,是可以被浏览器认为是合法的跨域请求,也就是说是可以带上 Cookie 访问的。
试想一下,如果我们在 a.com 上放置一个 img 标签。当 b.com 的用户在 cookie 为过期的情况下访问 a.com,此时浏览器会向 b.com 发送一个指向http://b.com/del?id=1的GET请求,并且这个请求是带上 Cookie 的,而 b.com 的服务器仅仅是通过 cookie 进行权限判断,那么服务器就会进行相应的操作,比如假设此处为删除某个文章,用户在不知情的情况下便已完成操作。
CSRF 能够造成的危害
1、篡改目标网站上的用户数据;
2、盗取用户隐私数据;
3、作为其他攻击向量的辅助攻击手法;
4、传播 CSRF 蠕虫。
CSRF 的利用方式
1、通过 HTML 标签发送合法的跨域请求
2、通过 Ajax 发送请求(由于 CORS 机制的存在,一般不使用)
这里涉及到同源策略,如果不是很清楚可以先去了解一下。
我们知道,根据同源策略的规定,跨域请求是不允许带上 Cookie 等信息的,可是出于种种考虑最终没有进行完全禁止,即存在某些合法的跨域请求。
通常由 HTML 标签src、lowsrc等属性产生的跨域请求是被浏览器认为是合法的跨域请求,并且此时并不需要 javascript 的参与。
由 HTML 标签发出的合法跨域请求与正常的用户点击发出的请求相比所不同的是:两者请求头中的 Referer 值不同。
不过值得说明的是 IE 浏览器在面对这种情况时会判断本地 Cookie 是否带上 P3P 属性,如果仅仅是内存Cookie则不受此影响。
CSRF 不仅仅只能针对 GET 请求,也可以针对 POST 请求,不过只能使用 from 标签进行自动提交,注意此处需用到 javascript。
除了通过 HTML 标签发送跨域请求外,还可以通过 Ajax 来发送跨域情况,不过 Ajax 是严格遵守 CORS 规则的。
关于 CORS 规则,不清楚的可以去看看 evoA 大佬的一篇文章 《跨域方式及其产生的安全问题》:
https://xz.aliyun.com/t/4470#toc-11
简单来说就是需要存在 CSRF 漏洞的网站返回的请求头里的Access-Control-Allow-Oringin值为 ajax 请求发出的站点,注意这里的值不能为*,且Access-Control-Allow-Credentials的值为true再加上 xhr 的withCredentials属性也为true才能带上 Cookie 进行跨域请求,因利用条件较为苛刻,故通常情况下我们不使用 Ajax 来进行 CSRF 攻击。
通常使用 Ajax 来跨域进行 CSRF 攻击的漏洞一般都配合 XSS 漏洞,此时的 Ajax 与目标域相同,不受 CORS 的限制。
CSRF 利用实例
攻击者构造恶意 html,通过引诱用户/管理员访问,触发 CSRF 漏洞。
CSRF+XSS 结合,产生的危害已几何倍数剧增。如果 CSRF 和 XSS 两个漏洞是在同一个域下的话,那么此时的 CSRF 已经变成了 OSRF 了,即本站点请求伪造(出自《黑客攻防技术宝典 Web 实战篇第二版》p366),此时已经变成XSS的请求伪造攻击,本文不在赘述。
我们知道网站 api 返回的数据类型一般为 json 型或 Array 型,这里我们仅讨论 json 型。
当我们需要调用远程 api 时 json 返回的数据一般如下:
user({"name":"Yunen","work":"Student","xxxx":"xxxxxxxxx",......})
这是因为开发者如果需要调用远程服务器的 api 获取 json 数据,由于同源策略的限制,通过 ajax 获取就会显得比较麻烦,相比之下
``
function user(data){
console.log(data);//此时的json数据已经存储进了data变量中
}
这种远程 api 接口十分容易受到 CSRF 攻击,我们可以通过修改 callback 参数值并添加自定义函数,如: