什么是 CSRF ?跨站请求伪造如何防御

摘要:跨站请求伪造(Cross-site request forgery,缩写为 CSRF),是一种挟制用户在当前已登录的 Web 应用程序上执行非本意的操作的攻击方法。简单地说,是攻击者通过一些技术手段,欺骗用户的浏览器去访问一个自己曾经认证过的网站,并运行一些操作。

跨站请求伪造(Cross-site request forgery,缩写为 CSRF),是一种挟制用户在当前已登录的 Web 应用程序上执行非本意的操作的攻击方法。

简单地说,是攻击者通过一些技术手段,欺骗用户的浏览器去访问一个自己曾经认证过的网站,并运行一些操作(如发邮件,发消息,请求授权,财产操作等)。由于浏览器曾经认证过,所以被访问的网站会认为是真正的用户操作而去运行。

攻击细节

比如用户 Tom 登录了某银行网站(假设为 http://www.examplebank.com/),转账地址为:

http://www.examplebank.com/withdraw?account=AccoutName&amount=1000&for=PayeeName

其中 AccoutName 为用户账户,PayeeName 为转账账户,1000 为转账金额。

登录后 Cookie 里会包含登录用户的 SessionId,攻击者 Jerry 可以在另一个网站上放置如下代码:

<img src="http://www.examplebank.com/withdraw?account=Tom&amount=1000&for=Jerry">

这种恶意的网址可以有很多种形式,藏身于网页中的许多地方,攻击者也不需要控制放置恶意网址的网站。例如他可以将这种地址藏在论坛,博客等任何用户生成内容的网站中。

如果用户 Tom 误点了上面这张图片,由于相同域名的请求会自动带上 Cookie,Cookie 里带有正常登录用户的 SessionId,而他之前刚访问过银行不久且未退出登陆,登录信息尚未过期,那么他就会损失 1000 资金,被转到攻击者 Jerry 的账户。

什么是 CSRF ?跨站请求伪造如何防御

通过例子能够看出,攻击者并不能通过 CSRF 攻击来直接获取用户的账户控制权,也不能直接窃取用户的任何信息。他们能做到的,是 欺骗用户浏览器,让其以用户的名义运行操作

这意味着如果服务端没有合适的防御措施的话,用户即使访问熟悉的可信网站也有受攻击的危险。

CSRF 攻击的根本原因在于,对于同样域名的每个请求来说,它的 Cookie 都会被浏览器自动带上发送给服务端,这个是浏览器的机制决定的,所以 Cookie 存在 CSRF 攻击风险。

这是利用了 Web 中用户身份认证的一个漏洞:简单的身份认证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的

防御措施

提交验证码

在表单中增加一个随机的数字或字母验证码,通过强制用户和应用进行交互,来有效地遏制 CSRF 攻击。

检查 Referer

HTTP 头中有一个 Referer 字段,这个字段用以标明请求来源于哪个地址。在处理敏感数据请求时,通常来说,Referer 字段应和提交请求页面来自于同一域名。

以上文银行操作为例,当用户提交转账请求时,Referer 值就是转账按钮所在页面的 URL。

而攻击者要对银行网站实施 CSRF 攻击,会在其它地方(如论坛、博客等)构造请求链接,当用户通过“包含恶意链接”的网站发送请求到银行时,该请求的 Referer 是指向“包含恶意链接”的网站 URL。

因此,要防御 CSRF 攻击,银行网站只需要对于每一个转账请求验证其 Referer 值,如果是以 examplebank.com 开头的域名,则说明该请求是来自银行网站自己的请求,是合法的。

如果 Referer 是其它网站的话,就有可能是 CSRF 攻击,则拒绝该请求。

这种方法简单易行,工作量低,仅需要在关键访问处增加一步校验。但这种方法也有其局限性,因其完全依赖浏览器发送正确的 Referer 字段。

虽然 HTTP 协议对此字段的内容有明确的规定,但并无法保证来访的浏览器的具体实现,亦无法保证浏览器没有安全漏洞影响到此字段。并且也存在攻击者攻击某些浏览器,篡改其 Referer 字段的可能。

Token 验证

CSRF 攻击之所以能够成功,是因为攻击者可以完全伪造用户的请求,该请求中所有的用户验证信息都是存在于 Cookie 中,因此攻击者可以在不知道这些验证信息的情况下,直接利用用户自己的 Cookie 来通过安全验证。

要抵御 CSRF,关键在于在请求中放入攻击者所不能伪造的信息,并且该信息不存在于 Cookie 之中。

在 HTTP 请求中以参数的形式添加一个随机产生的 Token,并在服务器端建立一个拦截器来验证这个 Token,假设请求中没有 Token 或 Token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。

Token 须要足够随机,敏感的操作应该使用 POST 而不是 GET,以 Form 表单的形式进行提交,能够有效避免 Token 泄露。

CSRF Token

CSRF Token 也是使用 Token 并进行验证,这里并非把 Token 以参数的形式置于 HTTP 请求 URL 中,而是把它放到 HTTP 头中自己定义的属性里。

通过 XMLHttpRequest 这个类,能够一次性给全部该类请求加上 csrftoken 这 HTTP 头属性,并把 Token 值放入当中。

这种方法攻克了在请求中添加 Token 的不便,同一时候,通过 XMLHttpRequest 请求的地址不会被记录到浏览器的地址栏,也不用操心 Token 会透过 Referer 泄露到其它站点中去。

Samesite Cookie

为了从源头上解决这个问题,Google 改进了 HTTP 协议,为 Set-Cookie 响应头新增了 Samesite 属性,它用来标明这个 Cookie 是“第一方 Cookie”,不能作为“第三方 Cookie”,从而防止了 CSRF 攻击。

Samesite 有 3 个属性值,分别是 Strict、Lax、None,详细说明可查阅 Cookie 的工作机制和属性介绍

  • Strict 最为严格,完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie;
  • Lax 规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外;
  • None 为关闭 SameSite 属性。

其它

  • CSRF(跨站请求伪造)是服务端没有对用户提交的数据进行随机值校验,且对 HTTP 请求包内的 Referer 字段校验不严,导致攻击者可以利用用户的 Cookie 信息,伪造用户请求发送至服务端。
  • SSRF(服务端请求伪造)是服务端对用户提供的可控 URL 过于信任,没有对攻击者提供的 URL 进行地址限制和足够的检测,导致攻击者可以以此为跳板攻击内网或其他服务端。
  • XSS(跨站脚本攻击)是攻击者利用网站漏洞,从而实现窃取用户信息等。跟 CSRF 相比,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。
  • 重放攻击是将截获的数据包进行重放,达到身份认证等目的,是指攻击者发送一个目的主机已接收过的包,来达到欺骗系统的目的,主要用于身份认证过程,破坏认证的正确性。
  • 中间人攻击简称“MITM 攻击”,是一种“间接”的入侵攻击,通过拦截正常的网络通信数据,并进行数据篡改和嗅探,而通信的双方却毫不知情。
版权声明:本文为博主原创文章,未经博主允许不得转载。http://www.dedenotes.com/html/cross-site.html
(1)
打赏 微信扫一扫 微信 支付宝 QQ 扫码打赏

HTTP消息结构 HTTP请求报文和响应报文的格式

Dedenotes 赞(3)

HTTP 协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,基于 TCP/IP 通信协议来传递数据(HTML 文件, 图片文件, 查询结果等),所有的 WWW(World Wide Web)文件都必须遵守这个标准。

防止表单重复提交的 4 种方法

Dedenotes 赞(3)

平时开发的项目中可能会出现下面这些情况:由于用户误操作,多次点击表单提交按钮;由于网速等原因造成页面卡顿,用户重复刷新提交页面;黑客或恶意用户使用 Postman 等工具重复恶意提交表单(攻击网站)。

meta

Dedenotes 赞(3)

meta 是 html 语言 head 区的一个辅助性标签,位于文档的头部,不包含任何内容,标签的属性定义了与文档相关联的名称/值对。meta 标签可提供相关页面的元信息(meta-information),比如针对搜索引擎和更新频度的描述和关键词。