CSRF基本概念
CSRF(即跨站请求伪造)是指利用受害者尚未失效的身份认证信息、(cookie、会话等),诱骗其点击恶意链接或者访问包含攻击代码的页面,在受害人不知情的情况下以受害人的身份向(身份认证信息所对应的)服务器发送请求,从而完成非法操作(转账,改密码等)。
- CSRF:属于业务逻辑漏洞,在服务器看来,所有请求都是合法正常的
- XSS、SQL注入等:都是属于技术漏洞
- XSS是基于客户信任服务器,而CSRF是基于服务器信任客户(经过身份验证的)
因为CSRF攻击,会重复利用用户的 Cookie,而说到 Cookie,就得先从 HTTP 协议开始讲起。
HTTP协议
无记忆性
HTTP是一种无状态协议,即服务器不会保留与客户交易时的状态。
用户A在很短的时间间隔内向Web服务器发送了两次同样的请求,服务器并不会因为已经响应了该请求一次就不对第二次请求进行响应,因为服务器并不知道已经响应过一次该请求。
假设用户在网站A的某一个页面上已经完成了登录操作,当在该网站的另一个页面上执行的操作需要验证用户登录的时候仍然需要用户再次登录,因为HTTP并不知道你已经登录了,它不会维持你的登录状态。
因为要多次登录太过麻烦,为了让服务器能够记住用户引入了 Cookie 机制
Cookie机制
当用户访问站点的时候,站点会为该用户分配一个 Cookie 值,站点使用该 Cookie 值来标记用户,当用户浏览器接受到包含 Cookie 值得数据包后,会将 Cookie 得值取出,存放到浏览器中,随后浏览器会在发往该站点得数据包中自动得填充该 Cookie 值。Cookie 的值的填充是浏览器的行为。
当浏览器自动完成Cookie的填充,目标网站会误认为该数据包就是管理员发送的,会以管理员的权限进行相关的操作。
CSRF 的防御
添加HTTP Referer
这个Referer字段主要是标明我们请求的来源,当我们通过一个恶意站点去访问一个可信任的站点的时候,可信任站点其实是能够识别这个请求是来自恶意站点的,因为Referer字段会标明它的来源
以百度里面的一个文件为例
站点还可以对一些敏感操作限制其Referer字段的值,比如某站点转账的时候使用:
http:bank.example/withdraw?account=bob&amount=10000000&for=Mallory
那么转账的操作一定是用户登录知乎在本站点的页面上操作的,因为可以将Referer字段限制为只允许本站点。
anti-csrf-token
CSRF成功的原因在于站点对于用户身份的辨别依赖于Cookie,因此攻击者可以在不知道用户口令的情况下直接使用用户的Cookie来通过安全验证。
在HTTP请求中以参数的形式加入一个随机产生的Token,服务器接收到用户请求后会验证Token,如果没有Token或者Token不正确都会被认为是攻击而直接丢弃。
GET请求
http://url?csrftoken=tokenvalue
POST请求
<input type="hidden" name="csrftoken" value="tokenvalue" />
Token的制作
- Token 由 Web 应用程序添加到数据包中(需要开发者介入)
- Cookie 由浏览器添加到数据包中
之所以会存在CSRF是因为浏览器会自动的将本地的 Cookie 添加到数据包,但是 Token 浏览器是不知道的,是由网站的应用程序添加到数据包中。
还需注意的是,攻击者可以在网站发布自己服务器的地址,当用户点击了该地址后,由于该站点会在地址后面添加Token,也就造成了Token的泄露。
站点对内链和外链要进行区分,只在内链中添加Token,对于外链就不添加Token。