Django之XSS&CSRF
一、XSS
1.1 何为XSS?
跨站脚本攻击(Cross Site Scripting),为了不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的(百度百科)。
1.2 具体表现
Django默认情况下会阻止比如<script>等违法字段的渲染,比如向前端发送以下代码:
<script> alert('xxxx') </script>
在前端渲染时还是会将以上代码原封不动的进行展示。
此时,我们可以在前端或后端加入相应字段来告诉程序输入字段为安全的。
前端实现
{% for item in comments %}
<p>{{ item|safe }}</p> <!-- 在需要展示的数据后面加入“|safe”前端即可认为该数据为安全的,将按照HTML语法进行展示 -->
{% endfor %}
后端实现
def backstage_safe(request):
'''后端实现安全展示'''
from django.utils.safestring import mark_safe #引入mark_safe模块实现安全展示
temp = "<a href='http://www.baidu.com'>百度</a>"
newtemp = mark_safe(temp)
return render(request,'test.html',{'temp':newtemp})
总结:
我们需要慎用safe/mark_safe,在存在可能的注入的情况下坚决不使用,如必须使用,需在后端对关键字进行过滤。
#初始化评论内容为空列表
comments = []
def comment(request):
'''发表评论'''
if request.method == 'GET':
return render(request,'comment.html')
else:
content = request.POST.get('content')
#后台做关键字过滤
if 'script' in content:
return render(request,'comment.html',{'error':'输入错误字段!!!'})
else:
comments.append(content)
return render(request, 'comment.html')
二 、CSRF
2.1 何为CSRF?
CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性(百度百科)。
2.2 基本应用
主要应用在form表单中,在from表单中加入{% csrf_token %},
<form method="post" action="/csrf1/">
{% csrf_token %}
<input type="text" name="content">
<input type="submit" value="提交" />
</form>
加入后,在通过GET方式访问网站后,通过页面源代码检查发现{% csrf_token %}实则为:
我们可以看到,{% csrf_token %}处生成了input标签且带有一段随机字符串(每次访问都是不同的),如果是{{csrf_token }},则会直接在页面生成一段随机字符串。
于此同时,cookie中也被写入了数据:
当我们向后台发送数据时,该随机字符串会一起发送至后端,完成验证。
如果在form表单中未加入{% csrf_token %},访问后提交数据,会出现以下错误:
2.3 全站禁用
只需将settings.py中的'django.middleware.csrf.CsrfViewMiddleware', 注释掉即可
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
#'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
2.4 局部禁用
在不需要进行CSRF验证的函数上添加相应装饰器
#'django.middleware.csrf.CsrfViewMiddleware'不被注释
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def csrf1(request):
if request.method == 'GET':
return render(request,'csrf1.html')
else:
return HttpResponse('...')
2.5 局部使用
在需要进行CSRF验证的函数上添加相应装饰器
# 'django.middleware.csrf.CsrfViewMiddleware'被注释
from django.views.decorators.csrf import csrf_protect
@csrf_protect
def csrf1(request):
if request.method == 'GET':
return render(request,'csrf1.html')
else:
return HttpResponse('...')
2.6 CBV中的使用
from django.views import View from django.utils.decorators import method_decorator @method_decorator(csrf_protect,name='dispatch') #name指定加装饰器的方法,如为'dispatch'则所有方法加上装饰器 class Foo(View): def get(self,request): pass def post(self,request): pass
注:关于SCRF对CBV加装装饰器的问题上,只能在类上进行装饰器加装,不能单独在方法上加装,但可以在继承基类的dispatch()方法上加装:@method_decorator(csrf_exempt)。
2.7 Ajax之SCRF
方式一:SCRF放置在data中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% csrf_token %}
<input id="content" type="text" name="content" >
<input type="button" id="submit-button" value="Ajax提交">
<script src="/static/jquery-3.2.1.js"></script>
<script>
$("#submit-button").click(function () {
var csrf = $('input[name="csrfmiddlewaretoken"]').val();
var content = $('#content').val();
$.ajax({
url: '/csrf1/',
type: 'POST',
data: { "content":content,'csrfmiddlewaretoken': csrf}, <!-- 不加则会报错,也可通过'{{ csrf_token }}'直接获取 -->
success:function(arg){
console.log(arg);
}
});
});
</script>
</body>
</html>
方式二:SCRF放置在放在请求头中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% csrf_token %}
<input id="content" type="text" name="content" />
<input type="button" id="submit-button" value="Ajax提交">
<script src="/static/jquery-3.2.1.js"></script>
<script src="/static/jquery.cookie.js"></script> <!-- 有关cookie操作的一个插件 -->
<script>
$("#submit-button").click(function (){
var token = $.cookie('csrftoken'); <!-- 可通过$.cookie('k','v')进行cookie设置 -->
var content = $('#content').val();
$.ajax({
url: '/csrf1/',
type: 'POST',
headers:{'X-CSRFToken': token}, <!-- 名称固定为'X-CSRFToken' -->
data: { "content":content},
success:function(arg){
console.log(arg);
}
})
})
</script>
</body>
</html>
注:一般POST请求需要带SCRF请求



浙公网安备 33010602011771号