Django-CSRF的理解

来源:互联网 发布:python决策树结构 编辑:程序博客网 时间:2024/05/17 22:20

CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。通俗来讲,就是以你的身份,来制造恶意请求。

危害:

CSRF这种攻击方式在2000年已经被国外的安全人员提出,但在国内,直到06年才开始被关注,08年,国内外的多个大型社区和交互网站分别爆出CSRF漏洞,如:NYTimes.com(纽约时报)、Metafilter(一个大型的BLOG网站),YouTube和百度HI……而现在,互联网上的许多站点仍对此毫无防备,对其进行防范的资源也相当稀少,以至于安全业界称CSRF为“沉睡的巨人”。

举个栗子

  1. 浏览器打开了银行系统,并且登录了
  2. 在没有关闭的情况下,又开了Tab,打开了一个黄色网站
  3. 你在黄网中看到了一个劲爆的链接(假设该名字为:xxx女星劲爆写真,其实真实的url为该银行系统转账链接)
  4. 而你不小心点了,因为你的银行系统页面未关闭,并且浏览器还存有你登录的Cookie,所以你的钱就被这样盗走了
  5. 就算你的银行系统关闭了,但是你的浏览器保存它的Cookie未过期的话,点了连接仍可以盗走你的钱

Django对CSRF防护

对于上面的栗子,楼主建议广大朋友千万不要上黄网,不要随便点开什么链接。回归正题,Django第一次来自客户端的请求时,都会在服务器上产生一个Token,每次Post请求都会要求带上这个Token,否则将不是安全的连接,将会被阻止,返回403错误。那我们怎么在Django中进行设置呢?起始Django本身就帮你做好了CSRF防护,在settings中它自动就帮你加上了‘django.contrib.auth.middleware.AuthenticationMiddleware’。我们只需要在form表单里面添加{% csrf_token %},进行post请求时,就自动将这个Token提交到了服务器,就表示你这个请求是安全的。
- form表单设置

<form method="POST" action="/login/" >    <!-- 固定写法 -->    {% csrf_token %}    <p>        <input type="text" name="name" placeholder="用户名">    </p>    <p>        <input type="password" name="password" placeholder="密码">    </p>    <input type="submit" value="提交"></form>
  • Ajax请求时设置
<script src="/static/jquery-3.2.1.js"></script><script src="/static/jquery.cookie.js"></script><script>    $(":button").click(function(){        $.ajax({            $.ajax({                url:"/login/",                type:"POST",                data:{"name":"python","password":"123"},                headers:{"X-CSRFtoken":$.cookie("csrftoken")},                success:function (data) {                    console.log("success");                }            })        })    })</script>

csrf_protect和csrf_exempt

  • csrf_protect:对单个网络请求进行保护,即便在settings的中间件中没有设置:’django.middleware.csrf.CsrfViewMiddleware’,也照样会进行保护
from django.views.decorators.csrf import csrf_protect@csrf_protectdef main(request):    username = request.session.get("has_login",None)    return render(request,"welcome.html",{"username":username})
  • csrf_exempt:对单个网络请求取消保护,即使在settings添加了csrf中间件也不会进行保护
from django.views.decorators.csrf import csrf_exempt@csrf_exemptdef main(request):    username = request.session.get("has_login",None)    return render(request,"welcome.html",{"username":username})

参考资料:http://www.cnblogs.com/hyddd/archive/2009/04/09/1432744.html
http://baike.baidu.com/item/CSRF