框架与CSRF防御
2012-04-12 19:22
162 查看
框架与CSRF防御
CSRF攻击的目标,一般都会产生“写数据”操作的URL,比如“增”、“删”、“改”;而“读数据”操作并不是CSRF攻击的目标,因为在CSRF的攻击过程中攻击者无法获取到服务器端返回的数据,攻击者只是借用户之手触发服务器动作,所以读数据对于CSRF来说并无直接的意义(但是如果同时存在XSS漏洞或者其他的跨域漏洞,则可能会引起别的问题,在这里,仅仅就CSRF对抗本身进行讨论)。因此,在Web应用开发中,有必要对“读操作”和“写操作”予以区分,比如要求所有的“写操作”都使用HTTP POST。
在很多讲述CSRF防御的文章中,都要求使用HTTP POST进行防御,但实际上POST本身并不足以对抗CSRF,因为POST也是可以自动提交的。但是POST的使用,对于保护token有着积极的意义,而security
token的私密性(不可预测性原则),是防御CSRF攻击的基础。
对于Web框架来说,可以自动地在所有涉及POST的代码中添加token,这些地方包括所有的form表单、所有的Ajax
POST请求等。
完整的CSRF防御方案,对于Web框架来说有以下几处地方需要改动。
(1)在Session中绑定token。如果不能保存到服务器端Session中,则可以替代为保存到Cookie里。
(2)在form表单中自动填入token字段,比如 <input type=hiddenname="anti_csrf_token"
value="$token" />。
(3)在Ajax请求中自动添加token,这可能需要已有的Ajax封装实现的支持。
(4)在服务器端对比POST提交参数的token与Session中绑定的token是否一致,以验证CSRF攻击。
在Rails
中,要做到这一切非常简单,只需要在ApplicationController中增加一行即可:
protect_from_forgery :secret =>"123456789012345678901234567890..."
它将根据secret和服务器端的随机因子自动生成token,并自动添加到所有form和由Rails生成的Ajax请求中。通过框架实现的这一功能大大简化了程序员的开发工作。
在Django中也有类似的功能,但是配置稍微要复杂点。
首先,将 django.middleware.csrf.CsrfViewMiddleware添加到 MIDDLEWARE_CLASSES中。
('django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',)
然后,在form表单的模板中添加token。
<form action="."method="post">{% csrf_token %}
接下来,确认在View层的函数中使用了django.core.context_processors.csrf,如果使用的是 RequestContext,则默认已经使用了,否则需要手动添加。
from django.core.context_processors import csrf
from django.shortcuts import render_to_response
def my_view(request):
c = {}
c.update(csrf(request))
# ...view code here
returnrender_to_response("a_template.html", c)
这样就配置成功了,可以享受CSRF防御的效果了。
在 Ajax请求中,一般是插入一个包含了token的HTTP头,使用HTTP头是为了防止token泄密,因为一般的JavaScript无法获取到HTTP头的信息,但是在存在一些跨域漏洞时可能会出现例外。
下面是一个在Ajax中添加自定义token的例子。
$(document).ajaxSend(function(event, xhr,settings) {
functiongetCookie(name) {
varcookieValue = null;
if(document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string beginwith the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
functionsameOrigin(url) {
//url could be relative or scheme relative or absolute
varhost = document.location.host; // host + port
varprotocol = document.location.protocol;
varsr_origin = '//' + host;
varorigin = protocol + sr_origin;
//Allow absolute or scheme relative URLs to same origin
return (url == origin || url.slice(0, origin.length + 1) == origin +'/') ||
(url == sr_origin || url.slice(0,sr_origin.length + 1) == sr_origin + '/') ||
// or any other URL that isn't scheme relative or absolute i.e relative.
!(/^(\/\/|http:|https:).*/.test(url));
}
functionsafeMethod(method) {
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
if(!safeMethod(settings.type) && sameOrigin(settings.url)) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
}
});
在Spring MVC以及一些其他的流行Web框架中,并没有直接提供针对CSRF的保护,因此这些功能需要自己实现。
本文节选自《白帽子讲Web安全》一书。
图书详细信息:/article/1578731.html
相关文章推荐
- yii2框架-yii2的防御csrf攻击机制(十六)
- 框架与CSRF防御
- 框架与CSRF防御
- CSRF的防御解决过程
- php yii框架 post csrf
- CSRF攻击防御---验证HTTP Referer
- Django框架全面讲解 -- 跨站请求伪造(csrf)
- CSRF注入式攻击防御讲解
- CSRF的攻击与防御(转)
- YII2框架学习 安全篇(三) csrf攻击和防范
- CSRF的本质及防御
- CSRF攻击与防御策略
- CSRF的攻击与防御
- Yii框架防止sql注入,xss攻击与csrf攻击的方法
- CSRF——攻击与防御
- SpringMVC如何防御CSRF
- CSRF学习笔记之CSRF的攻击与防御以及审计【00x3】
- CSRF攻击与防御
- CSRF攻击介绍及防御
- 前端安全(XSS、CSRF防御)