前端安全之CSRF攻击

CSRF定义

CSRF,即(Cross-site request forgery), 中文名为跨站请求伪造。是一种挟持用户在当前已登录的Web应用程序上执行非本意的操作的一种攻击方式。CSRF攻击的本质在于利用用户的身份,执行非本意的操作。根据CSRF的全名,可以得出的结论是:CSRF的请求是跨域且伪造的

跨域指的是请求来源于其他网站。比如说,目标网站上的删除文章功能接收到来自其他网站的删除文章的请求,那么这个请求就是跨域的。

伪造指的是如果这个请求不是用户自身的意愿,那么这个请求就是伪造的。

简单的说,跨站请求伪造的攻击是攻击者通过一些技术手段欺骗用户的浏览器去访问用户曾经认证过的网站并执行一些操作(如发送邮件、发消息、甚至财产操作如转账和购买商品等)。由于浏览器曾经认证过,所以被访问的网站会认为是真正的用户操作而去执行。这利用了web登录身份认证的一个漏洞:简单的身份认证只能保证请求来自用户的浏览器,但不能识别请求是用户自愿发出的

CSRF分类

  1. GET CSRF
  2. POST CSRF
    假如有这么一个场景,目标网站A的url:www.a.com。恶意网站B的url:www.b.com

GET CSRF:

两个网站的域名不一样,目标网站A上有一个删除文章的功能,通常是用户单击’删除文章‘链接时才会删除指定的文章。这个链接是www.a.com/blog/del?id=1, id代表不同的文章。实际上就是发起一个GET请求。

如果在目标网站A上存在XSS漏洞,那么可以利用这个XSS漏洞来进行攻击。注意,XSS攻击是在用户的浏览器上进行的。如果对XSS攻击不熟悉的朋友,可以看看上篇文章。

  1. 使用Ajax发起一个GET请求,因为是在目标网站上,所以符合同源策略。请求参数为id=1, 请求目标地址为www.a.com/blog/del
  2. 或者在目标网站A上动态创建一个标签(script, img, iframe等),将其src指向www.a.com/blog/del?id=1, 那么攻击就会发起。实际上通过这种方式发起的请求就是一个GET请求。
  3. 最后欺骗用户登录目标网站A,那么攻击就会发生。

如果在目标网站A上不存在XSS漏洞,那么可以利用GET CSRF进行攻击

  1. 无法使用Ajax发起GET请求。因为CSRF请求是跨域的,而Ajax有同源策略的限制。
  2. 可以通过在恶意网站B上静态或者动态创建img,script等标签发起GET请求。将其src属性指向www.a.com/blog/del?id=1。通过标签的方式发起的请求不受同源策略的限制。
  3. 最后欺骗已经登录目标网站A的用户访问恶意网站B,那么攻击就会发生。此时恶意网站B的请求是身份认证后的。

对比CSRF和XSS攻击可以看出,CSRF攻击有以下几个关键点

  1. 请求是跨域的。可以看出请求是从恶意网站B上发出的
  2. 通过img, script等标签来发起一个GET请求。因为这些标签不受同源策略的限制
  3. 发出的请求是身份认证后的。这一点是CSRF中最重要的一点。如以下代码

恶意网站B发出的删除文章的GET请求的请求头

GET /blog/del?id=1 HTTP/1.1
Host: www.a.com
Referer: http://www.b.com/csrf.html
Connection: Keep-Alive
Cookie: name=kk
Other-Request-Name: Other-Request-Value:

目标网站A发出的删除文章的GET请求的请求头

GET /blog/del?id=1 HTTP/1.1
Host: www.a.com
Referer: http://www.a.com/blog/
Connection: Keep-Alive
Cookie: name=kk
Other-Request-Name: Other-Request-Value:

对比以上的代码可以看出,只有Referer字段不同。也就是说,只有请求来源不相同,而发送删除文章的请求时都会带上相同的cookie信息。这样的请求就是身份认证后的,CSRF攻击就会成功。

POST CSRF:

POST请求实际上就是在恶意网站B上发起一个POST请求,同样的,这个请求也是跨域和身份认证后的。如静态或动态的创建一个form表单,当用户访问到这个恶意网站B时,就会提交这个表单。

假如目标网站A上有‘写文章’的功能,那么我们就可以动态创建form标签,然后修改文章的题目。

www.b.com/csrf.html

function setForm () {
    var form = document.createElement('form')
    form.action = 'www.a.com/blog/article'
    form.methods = 'POST'
    var input = document.createElement('input')
    input.type = 'text'
    input.value = 'csfr攻击啦!'
    input.id = 'title'
    form.appendChild(input)
    document.body.appendChild(form)
    form.submit()
}
setForm()

上面代码可以看出,动态创建了form表单,然后调用submit方法。就可以通过跨域的伪造请求来实现修改目标网站A的某篇文章的标题了。

以上说了GET和POST的CSRF攻击。本质上都是欺骗用户以自己的身份去执行非本意的操作。欺骗流程大致如下

  1. 首先欺骗用户登录目标网站。
  2. 然后欺骗用户登录恶意网站。这种恶意的网站有很多种形式,藏身于网页中的许多地方。此外,攻击者也不需要控制放置恶意网址的网站。例如他可以将这种地址藏在论坛,博客等任何用户生成内容的网站中。这意味着如果服务器端没有合适的防御措施的话,用户即使访问熟悉的可信网站也有受攻击的危险。

CSRF危害

  1. 模拟表单提交盗取用户资金。实际上就是上面所说的POST CSRF攻击
  2. 篡改目标网站上的用户数据。
  3. 盗取用户隐私数据

CSRF防范

1. 检测请求头中的Referer字段

从GET CSRF例子中可以看到,目标网站A和恶意网站B发出的请求中,请求头唯一的不同就是Referer字段。通常来说,Referer字段通常与Host字段的域名是一样的。

以上面删除文章功能为例,在目标网站A中的Referer字段为http://www.a.com/blog/,而恶意网站B中的Referer字段为http://www.b.com/csrf.html。所以根据Referer字段与Host字段在同一域名下的规则,可以检测Referer字段值,如果发现其与Host值不在同一域名下,这时候服务器就能够识别出恶意的访问了。

2.添加检验token

由于CSRF的本质在于攻击者欺骗用户去访问自己设置的地址,所以如果要求在访问敏感数据请求时,要求用户浏览器提供不保存在cookie中,并且攻击者无法伪造的数据作为校验,那么攻击者就无法再执行CSRF攻击。这种数据通常是表单中的一个数据项。服务器将其生成并附加在表单中,其内容是一个随机数。即<input type="hidden" name="_csrf_token" value="xxxx">)的形式。

当客户端通过表单提交请求时,这个随机数也一并提交上去以供校验。正常的访问时,客户端浏览器能够正确得到并传回这个随机数,而通过CSRF传来的欺骗性攻击中,攻击者无从事先得知这个随机数的值,服务器端就会因为校验token的值为空或者错误,拒绝这个可疑请求。

为了防范CSRF,在需要增删改数据时,使用POST请求,而不要使用GET请求。

具体的方案如下:

  1. 服务端在收到客户端请求时,生成一个随机数,在渲染页面时将随机数埋入页面(一般埋入form表单中),<input type="hidden" name="_csrf_token" value="xxxx">)`的形式。每次刷新页面后这个随机数都会改变,并在服务器中存储。
  2. 服务端设置Set-Cookie, 把该随机数作为cookie种入用户浏览器。
  3. 当用户发送GET或POST请求时带上_csrf_token参数(对于form表单直接提交即可)
  4. 后台在接受到请求后解析请求头中的cookie字段,获取_csrf_token的值,然后和用户请求提交的_csrf_token值做比较。如果相等则表示请求来源是合法的。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容