Python-csrf

来源:互联网 发布:女程序员容易老吗 编辑:程序博客网 时间:2024/06/05 16:41

CSRF是伪造客户端请求的一种攻击,CSRF的英文全称是Cross Site Request Forgery,字面上的意思是跨站点伪造请求。

 

解决方法:

(1)在setting中:增加红色的三行

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.middleware.csrf.CsrfResponseMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
)

 

(2)页面上:在post提交的form下添加 {% csrf_token %}

(3)在views中增加

render_to_response(xxx.html', locals(), context_instance=RequestContext(request))

 

详细解释及应用请看下面部分:

以下摘自:The Django Book:第15章 贡献的其它子框架

CSRF防护
django.contrib.csrf包提供了容易使用的跨站点请求伪造Cross-Site Request Forgeries(CSRF)防护

CSRF解释
CSRF,也称为"session驾驭",它是一个Web站点安全开拓,当一个恶毒的网站欺骗用户未知的从一个他们已经认证站点载入
一个URL--这样就可以使用他们的认证状态,这起初可能有点难以理解,所以这里我们包含了两个例子:
一个简单的例子
比如说你已经在example.com登录了一个webmail帐号,这个webmail站点有一个"注销"按钮指向URL为example.com/logout--
即你为了注销所需要做的唯一的动作是访问example.com/logout页面
恶毒的站点可以通过把URL example.com/logout包含在他自己(恶毒的)页面的一个隐藏的iframe来强迫你访问该URL,这样
如果你在example.com登录了webmail帐号并访问有example.com/logout的iframe的恶毒页面,访问该恶毒页面的结果是将
你从example.com注销
显然,不按你的意愿从一个webmail站点注销不是令人恐怖的安全漏洞,但是同类型的开拓可以发生在任何"信任"用户的站点
--例如银行站点或电子商务站点
一个更复杂的例子
在上个例子中,example.com部分有故障,因为他允许通过HTTP GET方法做状态更改(即注销你自己),对任何请求需要HTTP
POST来在服务器更改状态是一个良好实践,但是即使Web站点需要POST来做状态改变对于CSRF也很易受到攻击
比方说example.com升级了它的"注销"功能为一个form按钮来通过POST到URL example.com/logout来请求,而且,注销form
包含下面隐藏域:

<input type="hidden" name="confirm" value="true" />


这保证了简单的POST到URL example.com/logout将不执行注销,为了让用户注销,用户必须通过POST并发送confirm POST变
量且值为'true'
但是不管额外的安全,这种方式仍然可以被CSRF开拓,恶毒的页面只需做一点更多的工作,取代在iframe载入example.com/
logout页面,它可以通过使用JavaScript和POST来调用该URL,并传递confirm=true变量
防止
这样的话,怎样防止你的站点被开拓呢?
第一步是确认所有的GET请求没有副作用,这样,如果恶毒的站点包含了一个你的页面作为iframe,它将没有坏作用
第二步是给每个POST表单一个隐藏域,值为隐秘的并从用户的session ID生成,这样,当在服务器端处理时检查隐秘域,如
果它不合法则触发一个异常
这就是Django的CSRF预防层做的事情

使用CSRF中间件
djang.csrf包只包含一个模块:middleware.py,该模块包含了Django的中间件类CsrfMiddleware,它实现了CSRF预防
为了使用它,把'django.contrib.csrf.middleware.CsrfMiddleware'添加到你的settings文件的MIDDLEWARE_CLASSes设置中
这个中间件需要在SessionMiddleware之后处理应答,所以CsrfMiddleware必须放在列表的SessionMiddleware之前,它也必
须在应答被压缩或切碎之前处理,所以CsrfMiddleware必须放在GZipMiddleware之后
一旦你将它添加到你的MIDDLEWARE_CLASSES设置中,你就完成了,这是你需要做的所有的事情

它怎样工作
如果你感兴趣,这里是关于CsrfMiddleware怎样工作,它做这两件事情:
1,它通过使用csrfmiddlewaretoken名和session ID加上密码的hash值来添加一个隐藏域到所有的POST表单来修改外出的请
求,如果没有session ID设置则中间件不修改应答,所以执行处罚对于不使用sessions的请求可以忽略
2,对于所有进来的有session cookie设置的POST请求,它检查csrfmiddlewaretoken存在并正确,如果不是这样,用户将得
到一个403HTTP错误,403错误页面的内容是"发现跨站点请求伪造,请求中止"的信息
这确保了只有你的网站的原始表单可以用来POST回数据
该中间件故意只针对HTTP POST请求(以及相应的POST表单),我们上面解释了,GET请求应该从来没有副作用,确保这点是你
自己的责任
不通过session cookie完成的POST请求不被预防,但是它们也不需要预防,因为恶毒的网站不会伪造这种类型的请求
为了防止更改非文本请求,中间件在修改它之前检查应答的Content-Type头部,只有格式为text/html或者application/xml
+xhtml的页面被修改

限制
CsrfMiddleware需要Django的session框架来工作(参考第12章),如果你正在使用一个自定义的手动惯例session cookie的
session或者认证框架,该中间件将不能帮助你
如果你的app用一些不寻常的方式创建HTML页面和表单--例如,如果它用JavaScript的document.write语句传递HTML碎片--你
可能迂回添加隐藏域到表单的过滤器,这种情况下,表单提交将一直出错(这会发生因为CsrfMiddleware使用正则表达式来在
页面发送到客户端之前添加csrfmiddlewaretoken域到你的HTML,而正则表达式有时候不能处理古怪的HTML),如果你怀疑这
可能发生,只需在你的浏览器查看源代码来看看csrfmiddlewaretoken是否插入到你的表单
访问http://en.wikipedia.org/wiki/Csrf来得到更多关于CSRF的信息和例子

原创粉丝点击