一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第22天,点击查看活动详情。
跨站请求伪造(英语:
Cross-site request forgery
),也被称为one-click attack
或者session riding
,通常缩写为CSRF
或者XSRF
, 是一种挟制用户在当前已登录的Web
应用程序上执行非本意的操作的攻击方法。
CSRF
就是利用用户的登录态发起恶意请求。
如何攻击
原理就是攻击者构造出一个后端请求地址,诱导用户点击或者通过某些途径自动发起请求。如果用户是在登录状态下的话,后端就以为是用户在操作,从而进行相应的逻辑。
假设网站中有一个通过 GET
请求提交用户评论的接口,那么攻击者就可以在钓鱼网站中加入一个图片,图片的地址就是评论接口。
<img src="http://www.domain.com/xxx?comment='attack'"/>
使用
POST
方式提交请求是不是就没有这个问题了呢?其实并不是,使用这种方式也不是百分百安全的,攻击者同样可以诱导用户进入某个页面,在页面中通过表单提交POST
请求。
具体操作示例:
- 用户在A网站登录接口是get,登录后正常访问
- 此时有一个B网站(危险网站)中有一个钓鱼图片地址就是A网站,用户打开B网站
img
自动发起请求 - 此时会带上A网站的cookie,B网站就窃取了用户在A网站的信息
// 1. 假设A网站是taobao.com,登录接口是http://taobao.com/api/login,用户已登录
// 2. 在B网站中
<body>
<!-- 利用img自动发送get请求 -->
<img src="http://taobao.com/api/login" />
</body>
// 此时会带上A网站的cookie
在A网站下发cookie的时候,加上sameSite=strict
,这样B网站在发送A网站请求,就不会自动带上A网站的cookie,保证了安全
res.setHeader('Set-Cookie', `username=poetry2;sameSite = strict;path=/;httpOnly;expires=${getCookirExpires()}`)
// NAME=VALUE 赋予Cookie的名称及对应值
// expires=DATE Cookie 的有效期
// path=PATH 赋予Cookie的名称及对应值
// domain=域名 作为 Cookie 适用对象的域名 (若不指定则默认为创建 Cookie 的服务器的域名) (一般不指定)
// Secure 仅在 HTTPS 安全通信时才会发送 Cookie
// HttpOnly 加以限制,使 Cookie 不能被 JavaScript 脚本访问
// SameSite Lax|Strict|None 它允许您声明该Cookie是否仅限于第一方或者同一站点上下文
如何防御
Get
请求不对数据进行修改- 不让第三方网站访问到用户
Cookie
- 阻止第三方网站请求接口
- 请求时附带验证信息,比如验证码或者
token
SameSite Cookies
:可以对Cookie
设置SameSite
属性。该属性表示Cookie
不随着跨域请求发送,可以很大程度减少CSRF
的攻击,但是该属性目前并不是所有浏览器都兼容。- 验证Referer:对于需要防范
CSRF
的请求,我们可以通过验证Referer
来判断该请求是否为第三方网站发起的。
CSRF 特点
- 攻击一般发起在第三方网站,而不是被攻击的网站。
- 攻击是利用受害者在被攻击网站的登录凭证,冒充受害者提交操作,仅仅是“冒用”,而不是直接窃取数据。
- 攻击者预测出被攻击的网站接口的所有参数,成功伪造请求。
在CSRF
攻击中,就Cookie相关的特性:
http
请求,会自动携带Cookie。- 携带的cookie,还是
http
请求所在域名的cookie。
CSRF攻击
,仅仅是利用了http
携带cookie的特性进行攻击的,但是攻击站点还是无法得到被攻击站点的cookie。这个和XSS
不同,XSS
是直接通过拿到Cookie等信息进行攻击的