CSRF(Cross Site Request Forgery)跨站点请求伪造:攻击者诱使用户在访问 A 站点的时候点击一个掩盖了目的的链接,该链接能够在 B 站点执行某个操作,从而在用户不知情的情况下完成了一次对 B 站点的修改。
CSRF 实现
Cookie 策略
Cookie 分为 Session Cookie(临时 Cookie) 和 Third-party Cookie(本地 Cookie)。本地 Cookie 有失效时间,在失效时间内都可以使用。临时 Cookie 则在浏览器关闭后立即失效。CSRF 攻击过程中,用户浏览器将上传 Cookie 作为认证信息(无需认证的除外)。如果用户同时正在访问 B 站点,那么就有活跃的临时 Cookie 将被上传。然而,如果用户并未打开 B 站点,但存有未失效的本地 Cookie,根据流量器安全策略的不同(IE 默认禁止在<img>、<iframe>、<script>、<link>等标签中发送本地 Cookie,Firefox 默认允许发送本地 Cookie;默认会拦截本地 Cookie 的浏览器:IE 6/7/8,Safari;默认不拦截本地 Cookie 的浏览器:Firefox 2/3,Opera,Google Chrome,Android),本地 Cookie 可能被上传认证,导致攻击成功。【安全建议:及时清除浏览器数据,及时关闭浏览过的网站】
P3P 头
The Platform for Privacy Preferences,P3P Header 是 W3C 制定的一项关于隐私的标准。如果网站返回给浏览器的 HTTP 头中包含有 P3P 头,则将允许浏览器发送本地 Cookie。在 IE 下即使是<iframe>、<script>等标签也将不再拦截本地 Cookie 的发送。由于 Cookie 是以域和 path 为单位设置的,因此 P3P 头设置后对 Cookie 的影响将扩大到整个域中的所有页面。【安全建议:在 CSRF 的防御中不能依赖于浏览器对第三方 Cookie 的拦截策略,因为如果设置了 P3P 头,则浏览器自身的拦截策略将失效】
GET 请求和 POST 请求
虽然常见的 CSRF 都由发送 GET 请求的方式实现攻击,但 POST 请求也是可以被利用来做 CSRF 攻击的。如果站点没有指定提交数据的请求方式,那么 GET 和 POST 均可发送控制请求。如果只能用 POST 请求,最简单的方法是,在页面中隐含地构造一个 form 表单,然后使用 JavaScript 自动提交这个表单。即,如果 A 站点为攻击者所控制,则只需让链接触发一个由 JavaScript 发送 POST 请求的动作;如果 A 站点非攻击者所能控制,则只需让链接指向一个能用 JavaScript 发送 POST 请求的 X 站点,由 X 站点做媒介,发送恶意请求的时候带上 B 站点的本地/临时Cookie。
Flash CSRF 和 CSRF Worm
Flash 有多种方式能够发起网络请求:POST、getURL、loadVars 等。IE 6/7 中,Flash 发送的网络请求可以带上本地 Cookie,IE 8 起禁用了该功能。
经过精心设计,CSRF 漏洞也可以用于蠕虫攻击——比如传播消息。
CSRF 防御
验证码
优点:简单有效
缺点:用户体验不佳
Referer Check
Referer Check 可被用于检查请求是否来自合法的“源”。常见的互联网应用,页面与页面之间都具有一定的逻辑关系,这种关系使得每个正常请求的 Referer 具有一定规律。检查 Referer 可以有效地防御跨站点的请求伪造。
缺陷:然而服务器并非总是能够提取到 Referer 属性,很多用户处于隐私保护的考虑,限制了 Referer 的发送,某些情况下浏览器也不会发送 Referer(比如 HTTPS 跳转到 HTTP)。
Anti CSRF Token
CSRF 的本质原因是重要操作的所有参数都是可以被攻击者猜测到的。因此 Anti CSRF Token 的原理就是,通过增加一个不可预测的请求参数 Token,来区分合法请求和非法请求,从而拒绝 CSRF。
Token 需要足够随机,而且应该作为一个“秘密”,仅为用户与服务器所共同持有。
实际应用中 Token 可以放在用户的 Session 中或浏览器的 Cookie 中【不建议】。推荐做法是将 Token 存放在页面表单(隐藏的 input 字段)和 Session 中,而且提交操作应该设置为 POST,避免 Token 泄露。切记,不要在 URL 中存放 Token,否则通过 Referer 可以被窃取。
当一个站点同时存在 XSS 和 CSRF 漏洞的情况下情况将变得不容乐观,攻击者可以通过 XSS 漏洞获取 Cookie 和 Token,然后轻易发起 CSRF 攻击。