CSRF,全称 Cross Site Request Forgery,跨站请求伪造,是一种欺骗受害用户在已登陆的web应用上按照攻击者的指令执行恶意操做的攻击行为。攻击的影响范围取决于受害用户所拥有的的权限,由于攻击者是依赖用户在当前会话中的鉴权进行恶意操做的。html
CSRF仅在用户已被受权的状况下才能生效。经过CSRF,攻击者能够绕开web应用的鉴权机制,进而利用受害者的用户权限对web应用进行恶意操做。好比网上银行等场景。web
下面是CSRF攻击的两个主要组成部分:django
(HTTP session和cookie机制请见cookie与session的区别以及在Django中的实现)api
CSRF攻击实际上就是利用了HTTP会话的cookie机制,由于浏览器会在每次请求中都带上与web应用关联的cookie。浏览器
假设这是一个合法的url,用于向指定的User用户转帐1000块钱。bash
http://example.com/transfer?amount=1000&account=User
复制代码
当用户发送该请求时,若是用户已经登陆过web应用且鉴权经过,则浏览器会在请求中自动携带包含鉴权信息的cookie,这样用户进行转帐时就不须要再次进行登陆验证;若是用户还未登陆鉴权,则会须要先进行登陆鉴权,而后浏览器才能进一步携带cookie信息发起转帐请求。 web应用须要拿到转帐请求中携带的cookie用于验证用户信息,才能得知是要从哪一个用户的帐户中将钱转出。cookie
若是web应用能够接受GET请求,那攻击者只须要在恶意连接的html中加入以下的代码,经过img标签自动向web应用伪造一个转帐请求。利用浏览器自动携带cookie的机制,就能够从用户帐户中盗走1000块钱。session
<img src="http://example.com/transfer?amount=1000&account=Fred" />
复制代码
该场景中的web应用除了存在CSRF漏洞之外,还有一个问题:任何的GET请求都应该是“只读“的,不该该对数据产生任何影响。因此该场景中的web应用设计是不合理的。post
下面是使用POST进行攻击的html表单代码网站
<h1>You Are a Winner!</h1>
<form action="http://example.com/api/account" method="post">
<input type="hidden" name="Transaction" value="withdraw" />
<input type="hidden" name="Amount" value="1000" />
<input type="submit" value="Click Me"/>
</form>
复制代码
试想以下攻击场景:
值得注意的是,SSL是没法防御CSRF攻击的。由于攻击者只须要在伪造请求中指定https访问便可。
最经常使用的CSRF防范机制就是使用csrf token机制。
注意,在POST表单中使用csrf token时,要确保表单是提交给本身的web应用的,而不是提交给外部的应用。好比在表单action中指定提交到baidu或者其余网站,别人是没法识别请求中的csrf token的,而且同时也存在泄漏csrf token的风险。
cookie由于其自动在请求中携带的特色,很容易受到CSRF攻击。攻击者不须要获取用户的cookie,也能够直接利用用户的cookie进行恶意操做。CSRF攻击的影响取决于用户所拥有的权限。
因此咱们在web应用设计中要注意,一方面是要严格遵照HTTP规范,GET请求必定是”只读“的,避免接收GET请求进行状态变动(如数据修改等);另外一方面是对于全部设计状态变动的请求,如POST、PUT、DELETE等,都须要进行csrf token校验。
【本文参考】