CSRF攻击

什么是CSRF攻击

CSRF攻击全称跨站请求伪造(Cross-site request forgery), 也被称为one-click attacksession riding, 通常缩写为CSRF或者XSRF. 尽管CSRF和XSS攻击很像, 但是两者的方式截然不同, 甚至可以说是相左的. XSS利用的是用户对指定网站的信任, CSRF利用的是网站对用户网页浏览器的信任. 我理解的是XSS是攻击者对浏览器下手, CSRF是对用户下手.

可以这么理解: 攻击者盗用受信任用户的身份, 以该用户的名已发送恶意请求.

CSRF攻击的原理

  1. 用户1访问受信任的网站A, 输入用户名和密码登录网站A.
  2. 登录成功之后, 网站A产生Cookie信息并返回给浏览器.
  3. 用户1在未退出登录网站A的情况下, 在同一浏览器, 访问网站B.
  4. 网站B接收到请求后, 携带网站A的Cookie信息, 发出一个请求去访问网站A
  5. 网站A在接收到网站B的请求之后, 会以用户1的权限处理该请求, 从而导致用户1的隐私泄漏和财产安全受到威胁.

常见的几种类型

  1. GET类型的CSRF:

    • 这种类型的CSRF利用非常简单, 只需要一个HTTP请求:
    1
    
    <img src=http://xxx.com/csrf?user=xxx />

    在访问这个img的页面后, 成功发出了一次HTTP请求.

  2. POST类型的CSRF:

    • 这种类型的CSRF没有GET型的大, 利用起来通常使用的是一个自动提交的表单:
    1
    2
    3
    4
    
    <form action=http://xxx.com/csrf.php method=POST>
      <input type="text" name="user" value="xxx" />
    </form>
    <script>document.forms[0].submit();</script>
  3. 其他类型CSRF:

    1
    
    <img src=http://admin:admin@192.168.1.1 />

    在访问这个img的页面后, 路由器会给用户一个合法的SESSION, 就可以进行下一步操作了.

防御手段

目前防御CSRF攻击主要有三种策略:

  1. 检查HTTP Referer字段

    根据HTTP协议, 在HTTP头中有一个字段叫Referer, 它记录了该HTTP请求的来源地址.

    优势: 简单易行, 网站的普通开发人员不需要操心CSRF的漏洞, 只需要在最后给所有安全敏感的请求统一增加一个拦截器来检查Referer的值就可以了. 特别是对于已有的系统来说, 不需要更改当前系统的任何代码和逻辑, 没有风险.

    劣势: 这种方式是把安全性都依赖于浏览器来保障, 对于一些低版本的浏览器来说, 是可以篡改Referer值的. 对于某些最新的浏览器, 虽然不能篡改Referer的值, 但是用户有些时候会认为Referer值会记录下用户的访问来源, 所以用户自己可以设置浏览器在发送请求的时候不再提供Referer. 这种情况下, 此种方式就会认为是CSRF攻击, 从而拒绝合法用户的访问.

  2. 添加校验token

    CSRF之所以能够成功是因为攻击者获取到了Cookie信息. 如果能够不只是依靠Cookie中的信息来抵御CSRF攻击, 那么就可以防御了. 所以这种方式就是在HTTP请求中以参数的形式加入一个随机产生的token, 并且在服务器端建立一个拦截器来验证这个token.

    优势: 这种方法比检查Referer更安全一些, token可以在用户登录之后产生并放与SESSION中, 然后每次请求时把token从SESSION中取出来进行比对.

    劣势: 难以保证token本身的安全.

    疑问: 可以做到每次验证token成功之后, 产生一个新的token是否可以避免此种方法可能产生的漏洞.

  3. 在HTTP头中自定义属性并验证

    这种方法也是使用token进行验证, 但是不是放在参数中, 而是放在HTTP请求头的自定义属性中. 通过XMLHttpRequest这个类, 可以一次性给所有该类请求加上csrftoken这个HTTP头属性, 并把token放进去.

    优势: 不会记录到浏览器的地址栏, 统一管理token输入输出, 可以保证token的安全性.

    劣势: 无法在非异步的请求上实施.

0%