Django框架之跨站请求伪造
跨站请求伪造(英语:Cross-site request forgery),也被称为one-click attack或者session riding,通常缩写为CSRF或者XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。
跟跨网站脚本(XSS)相比,XSS利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。
例如:
如果用户登录网络银行去查看其存款余额,他没有退出网络银行系统就去了自己喜欢的论坛去灌水,如果攻击者在论坛中精心构造了一个恶意的链接并诱使该用户点击了该链接,那么该用户在网络银行帐户中的资金就有可能被转移到攻击者指定的帐户中。
造成CSRF的原因
跨站请求伪造能否得逞,与以下几个方面密不可分,分别是浏览器对会话的处理,攻击者对Web应用有关URL的了解,应用程序赖以管理会话的信息对浏览器的透明性以及各种能够引发资源请求HTML标签等。
正常:
a. 先GET请求:
页面
隐藏:input 随机字符串
b. POST
数据
input 随机字符串
非法:
b. POST
数据
首先,我们来了解一些Web浏览器对于Cookie和HTTP身份验证信息之类的会话信息的处理方式。目前,浏览器会自动地发送标识用户对话的信息,而无需用户干预,换句话说,当浏览器发送这些身份信息的时候,用户根本感觉不到。假设站点A上有一个Web应用程序,并且受害者正好已经在该站点上通过了身份认证,这时,站点会向受害者发送一个cookie作为响应,这个cookie的作用是什么呢?主要是被站点作为用户会话的标志,即如果站点收到了带有受害者的cookie的请求,那么它就会把这个请求看作是已登录的受害者发来的。一般情况下,浏览器收到站点设置的cookie之后,每当向该站点发送请求的时候,浏览器都会“自动地”连同该cookie一起发出。
然后,我们再来讨论一下攻击者对Web应用程序URL的了解。如果应用程序没有在URL中使用跟会话有关的信息的话,那么通过代码分析或者通过访问该应用程序并查看嵌入HTML/JavaScript中的URL以及表单来了解应用程序有关的URL、参数和容许值。
接下来,我们讨论一下应用程序赖以管理会话的信息对浏览器的透明性问题。我们知道,为了提高Web应用的便利性,用来管理会话的信息,例如Cookie或者基于HTTP的身份验证(例如HTTP基本认证、非基于表单的认证)等敏感信息,都是由浏览器来存放的,并在每当向需要身份验证的应用程序发送请求时自动捎带上这些信息。也就是说,浏览器可以访问会话管理信息,如果Web应用程序完全依赖于这类信息来识别一个用户会话,这就为跨站请求伪造创造了条件。
上面所说的三个因素,是跨站请求伪造攻击的必要的条件,而下面所说的,是一个“锦上添花”的因素,即没有它也能发动跨站请求伪造攻击,但是有了它能使该攻击更加容易。这就是存在多种HTML标签,如果页面内出现这些标签,会立刻引起浏览器对http[s]资源的访问,例如图像标签img便是其中之一。
在Django中
django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成。而对于django中设置防跨站请求伪造功能有分为全局和局部。
全局:
中间件 django.middleware.csrf.CsrfViewMiddleware
局部:
- @csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
- @csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
注:from django.views.decorators.csrf import csrf_exempt,csrf_protect
应用
1、普通表单
veiw中设置返回值:
return render_to_response('Account/Login.html',data,context_instance=RequestContext(request))
或者
return render(request, 'xxx.html', data)
html中设置Token:
{% csrf_token %}
Form提交:
<form action="/icbc.html" method="POST">
{% csrf_token %}
<input type='text' name='from' />
<input type='text' name='to' />
<input type='text' name='money' />
<input type='submit' value='转账' />
2、Ajax
对于传统的form,可以通过表单的方式将token再次发送到服务端,而对于ajax的话,使用如下方式。
view.py
from django.template.context import RequestContext
# Create your views here.
def test(request):
if request.method == 'POST':
print request.POST
return HttpResponse('ok')
return render_to_response('app01/test.html',context_instance=RequestContext(request))
text.html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
{% csrf_token %}
<input type="button" onclick="Do();" value="Do it"/>
<script src="/static/plugin/jquery/jquery-1.8.0.js"></script>
<script src="/static/plugin/jquery/jquery.cookie.js"></script>
<script type="text/javascript">
var csrftoken = $.cookie('csrftoken');
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
function Do(){
$.ajax({
url:"/app01/test/",
data:{id:1},
type:'POST',
success:function(data){
console.log(data);
}
});
}
</script>
</body>
</html>
Ajax提交:
1)基于请求体:
function ajaxSubmit() {
$.ajax({
url: "/icbc.html",
type: 'POST',
data: {'k1':'v1','k2':'v2','csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val() },
success:function (arg) {
console.log(arg)
}
})
}
// 只能写在模板中
function ajaxSubmit() {
$.ajax({
url: "/icbc.html",
type: 'POST',
data: {'k1':'v1','k2':'v2','csrfmiddlewaretoken':"{{ csrf_token }}" },
success:function (arg) {
console.log(arg)
}
})
}
function ajaxSubmit() {
$.ajax({
url: "/icbc.html",
type: 'POST',
data: $('#f1').serialize(),
success:function (arg) {
console.log(arg)
}
})
}
// 以上都是放在请求体中
2)基于请求头:
a. 在cookie中获取csrftoken对应的值 l2kEqQLhR1gH0hh3ioZ1dfxT3iSwjXoKTf7GNFggJZ7E6DROB6k33L7vdqe5lV1v
b. 发送请求时,放在请求头中也可以
function ajaxSubmit() {
$.ajax({
url: "/icbc.html",
type: 'POST',
data: {'k1':'v1','k2':'v2'},
headers: {"X-CSRFToken": $.cookie('csrftoken')},
success:function (arg) {
console.log(arg)
}
})
}
跨站请求伪造对策
跨站请求伪造的危害非常之大,所以无论是用户还是开发人员都应该引起足够的重视,下面是给Web应用程序终端用户和Web应用程序开发人员的一些有用的建议。
用户:
因为CSRF漏洞有流行之趋势,所以建议用户遵循最佳实践来降低风险,可以降低风险的习惯包括:
使用Web应用程序之后立即登出
不要让浏览器保存用户名/口令,也不要让站点“记住”您不要使用同一个浏览器同时访问敏感的应用程序和随意冲浪;如果必须同时做多件事情的话,最好单独使用不同的浏览器。
对于支持HTM格式邮件/浏览器集成式软件以及集成了新闻阅读程序/浏览器的软件都会带来额外的风险,因为只要查看邮件或者新闻就有可能被迫执行一次攻击,所以使用这类软件时格外小心。
开发人员:
开发人员应当向URL添加跟会话有关信息。该攻击类型之所以得逞,是因为会话是由cookie唯一标识的,并且该cookie是由浏览器自动发送的。
如果我们在URL级别为会话生成其它相关信息,那么就会给攻击者为发动攻击而了解URL的结构造成更多的障碍。
至于其它的对策,虽然也无法解决该问题,但是能够使得利用该漏洞更加困难,例如使用POST而不是GET。虽然POST请求可以通过JavaScript进行模仿,但是它提高了发动这种攻击的难度。使用中间确认页也能带来相同的效果,比如“您确信要这样做吗?”之类的页面。虽然攻击者可以绕过这些措施,但是这些措施提供了实施攻击的难度。因此,不能完全依赖这些手段来保护您的应用程序。自动登出机制也能减轻这种攻击带来的危害,但这最终依赖于具体情况(一个整天跟有这种漏洞的网络银行程序打交道的用户所面临的风险要远远大于临时使用同一网络银行的用户所面临的风险)。
Django框架之跨站请求伪造的更多相关文章
- Django框架 之 跨域请求伪造
Django框架 之 跨域请求伪造 浏览目录 同源策略与Jsonp 同源策略 Jsonp jQuery对JSONP的实现 CORS 简介 两种请求 同源策略与Jsonp 同源策略 同源策略(Same ...
- Django之CSRF 跨站请求伪造
一.简介 1.点我了解什么是跨站请求伪造 2.django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成.而对 ...
- Django添加防跨站请求伪造中间件
第一步: 在全局设置中打开此中间件: MIDDLEWARE_CLASSES = [ ... 'django.middleware.csrf.CsrfViewMiddleware', ... ] ...
- Django之cfrs跨站请求伪造和xfs攻击
跨站请求伪造 一.简介 django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成.而对于django中设置防 ...
- django CBV装饰器 自定义django中间件 csrf跨站请求伪造 auth认证模块
CBV加装饰器 第一种 @method_decorator(装饰器) 加在get上 第二种 @method_decorator(login_auth,name='get') 加在类上 第三种 @met ...
- django的csrf跨站请求伪造
1.什么是跨站请求伪造 请看图: 我们自行写了一个网站模仿中国银行,用户不知道是否是真的中国银行,并且提交了转账信息,生成一个form表单,向银行服务器发送转账请求,这个form表单和正规银行网站的f ...
- Django之CSRF跨站请求伪造(老掉牙的钓鱼网站模拟)
首先这是一个测试的代码 请先在setting页面进行下面操作 注释完成后,开始模拟钓鱼网站的跨站请求伪造操作: 前端代码: <!DOCTYPE html> <html lang=&q ...
- django中csrftoken跨站请求伪造的几种方式
1.介绍 我们之前从前端给后端发送数据的时候,一直都是把setting中中间件里的的csrftoken这条给注释掉,其实这个主要起了一个对保护作用,以免恶意性数据的攻击.但是这样直接注释掉并不是理智型 ...
- Web框架之Django_09 重要组件(Django中间件、csrf跨站请求伪造)
摘要 Django中间件 csrf跨站请求伪造 一.Django中间件: 什么是中间件? 官方的说法:中间件是一个用来处理Django的请求和响应的框架级别的钩子.它是一个轻量.低级别的插件系统,用于 ...
随机推荐
- HDFS体系结构(NameNode、DataNode详解)
hadoop项目地址:http://hadoop.apache.org/ NameNode.DataNode详解 (一)分布式文件系统概述 数据量越来越多,在一个操作系统管辖的范围存不下了,那么就分配 ...
- LightOJ 1030 - Discovering Gold - [概率DP]
题目链接:https://cn.vjudge.net/problem/LightOJ-1030 You are in a cave, a long cave! The cave can be repr ...
- The "get" method should be used when the form is idempotent---正交的两个概念 get 幂等
https://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.1 17.13.1 Form submission method The me ...
- 2015 湘潭大学程序设计比赛(Internet)--D题-最小的数
最小的数 Accepted : 47 Submit : 276 Time Limit : 1000 MS Memory Limit : 65536 KB 题目描述 给你一个n位数,每次操作可以 ...
- 【Python】【Web.py】详细解读Python的web.py框架下的application.py模块
详细解读Python的web.py框架下的application.py模块 这篇文章主要介绍了Python的web.py框架下的application.py模块,作者深入分析了web.py的源码, ...
- 解决FileInputStream读取文本时 最后端会多出字符问题
使用 read(byte[]) 方法读取文本的时候,要用 String str = new String(byte[],int offset,int len) 来将数组中的元素转换为String字符串 ...
- HTML5-CSS3-JavaScript(4)
CSS3中 变形与动画相关属性 CSS3在原来的基础上新增了变形和动画相关属性,通过这些属性可以实现以前需要大段JavaScript才能实现的功能.CSS3的变形功能可以对HTML组件执行位移.旋转. ...
- Hardwood Species(stl map)
http://acm.sdut.edu.cn:8080/vjudge/contest/view.action?cid=203#problem/B 属于暴力 #include <stdio.h&g ...
- ID和Name
ID和Name都可以用来标识一个标记,Javascript分别有两个方法getElementById和getElementByName来定位Dom节点. 区别如下: 1.我们知道在网页做Post提交时 ...
- python输入与输出165
s = 'Hello,Runoob' print(s) str(s) print(s) print(repr(s)) print(1/7) print(str(1/7)) print(repr(1/7 ...