Django—XSS及CSRF
一、XSS
跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。
1. 工作流程
a. 恶意用户,在一些公共区域(例如,建议提交表单或消息公共板的输入表单)输入一些文本,这些文本被其它用户看到,但这些文本不仅仅是他们要输入的文本,同时还包括一些可以在客户端执行的脚本。如:
<script>
this.document = "*********";
alert('Not Safe');
</script>
b. 恶意提交这个表单
c. 其他用户看到这个包括恶意脚本的页面并执行,获取用户的cookie等敏感信息。

2. 实例-未防范XSS攻击
pinglu = [] # 评论列表 #提交表单
def commit(request):
if request.method == 'GET':
return render(request, 'commit.html')
else:
com = request.POST.get('commit')
pinglu.append(com)
return redirect('/index.html/') #查看评论页面
def index(request):
return render(request, 'index.html', {'commit': pinglu})
view.py
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>评论</h1>
<form action="/commit.html/" method="post">
<input type="text" name="commit">
<input type="submit" value="sumbit"> {{ error }}
</form>
</body>
</html>
commit.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>评论</h1>
{% for item in commit %}
<div>{{ item|safe }}</div>
{# item后加safe,默认数据安全,django不会做特殊处理#}
{% endfor %}
</body>
</html>
index.html
以上实例中,若在commit.html页面输入以下内容并提交:
<script> alert('恶意脚本') </script>
则会在index页面执行此行代码,弹出警告框(若包含恶意代码,则会执行)

3. 防范XSS攻击
- 最直接的方法就是对于无法控制的输入在html页面内不要使用safe
{# <div>{{ item|safe }}</div>#}
<div>{{ item }}</div>
- 也可以在views里进行过滤,防止特殊字符提交到数据库或网页内
def commit(request):
if request.method == 'GET':
return render(request, 'commit.html')
else:
com = request.POST.get('commit')
if '<script>' in com: # 过滤“<script>”关键字,防止恶意代码的提交
return render(request, 'commit.html', {'error': '此条评论有毒,已被和谐'})
else:
pinglu.append(com)
return redirect('/index.html/')

- 对于信任的链接或用户输入,使用 mark_safe 标记为安全
def make_safe(request):
from django.utils.safestring import mark_safe
temp = "<a href='http://www.baidu.com'>百度</a>"
#temp = mark_safe(temp)
return render(request, 'make_safe.html', {'temp': temp})
未使用mark_safe标记的链接

def make_safe(request):
from django.utils.safestring import mark_safe
temp = "<a href='http://www.baidu.com'>百度</a>"
temp = mark_safe(temp)
return render(request, 'make_safe.html', {'temp': temp})
使用mark_safe标记的安全链接

二、CSRF
CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。
1. 工作流程
攻击通过在授权用户访问的页面中包含链接或者脚本的方式工作:

2. django中如何防范
django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成。而对于django中设置防跨站请求伪造功能有分为全局和局部。
全局:
- 启用中间件 django.middleware.csrf.CsrfViewMiddleware

局部:
from django.views.decorators.csrf import csrf_exempt,csrf_protect
- @csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件
- @csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
3. django中的具体应用方法
- form表单中添加
{%csrf_token%}
若form表单中未添加{% csrf_token %},则会报403错误。
#settings.py中打开MIDDLEWARE设置
'django.middleware.csrf.CsrfViewMiddleware',
from django.shortcuts import render, HttpResponse, redirect def csrf_test(request):
if request.method == 'GET':
return render(request, 'csrf_test.html')
else:
return HttpResponse('ok')
views.py
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>csef_test</title>
</head>
<body>
<form action="/csrf_test.html/" method="post">
<input type="text" name="user" id="user">
<input type="submit" value="submit">
</form> </body>
</html>
csef_test.html

修改csef_test.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>csef_test</title>
</head>
<body>
<form action="/csrf_test.html/" method="post">
{% csrf_token %}
<input type="text" name="user" id="user">
<input type="submit" value="submit">
</form> </body>
</html>
form表单中添加{% csrf_token %}

- 全站禁用,即将settings.py中的 'django.middleware.csrf.CsrfViewMiddleware' 注释掉即可
- 基于FBV视图的局部禁用和使用
#settings.py
#启用 'django.middleware.csrf.CsrfViewMiddleware', from django.views.decorators.csrf import csrf_exempt @csrf_exempt
def csrf_test(request):
if request.method == 'GET':
return render(request, 'csrf_test.html')
else:
return HttpResponse('ok')
局部禁用
#settings.py
#禁用 #'django.middleware.csrf.CsrfViewMiddleware', from django.views.decorators.csrf import csrf_protect @csrf_protect
def csrf_test(request):
if request.method == 'GET':
return render(request, 'csrf_test.html')
else:
return HttpResponse('ok')
局部使用
- 基于CBV视图的(只能局部使用或禁用类,不能在类方法里局部使用或禁用
#settings.py
#禁用 'django.middleware.csrf.CsrfViewMiddleware', from django.views import View
from django.views.decorators.csrf import csrf_protect
from django.utils.decorators import method_decorator @method_decorator(csrf_protect, name='dispatch')
class Foo(View):
def get(self, request):
pass def post(self, request):
pass
局部使用
#settings.py
#启用 'django.middleware.csrf.CsrfViewMiddleware', from django.views import View
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator @method_decorator(csrf_exempt, name='dispatch')
class Foo(View):
def get(self, request):
pass def post(self, request):
pass
局部禁用
- Ajax提交数据时,携带CSRF
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>csef_test</title>
</head>
<body>
<form action="/csrf_test.html/" method="post">
{% csrf_token %}
<input type="text" name="user" id="user">
{# <input type="submit" value="submit">#}
<a onclick="submitForm();">Ajax提交表单</a>
</form> <script src="/static/jquery-3.2.1.js"></script>
<script>
function submitForm() {
var csrf = $("input[name='csrfmiddlewaretoken']").val()
var user = $("#user").val()
$.ajax({
url: '/csrf_test.html/',
type: 'POST',
data: {"user": user, "csrfmiddlewaretoken": csrf},
success: function (arg) {
console.log(arg);
}
})
}
</script>
</body>
</html>
Ajax重写csrf_test,html,csrf数据存放于data中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>csef_test</title>
</head>
<body>
<form action="/csrf_test.html/" method="post">
{% csrf_token %}
<input type="text" name="user" id="user">
{# <input type="submit" value="submit">#}
<a onclick="submitForm();">Ajax提交表单</a>
</form> <script src="/static/jquery-3.2.1.js"></script>
{#专门处理cookie的插件,提取cookie字符串#}
<script src="/static/jquery.cookie.js"></script> {#csrf数据放于data中#}
{#<script>#}
{# function submitForm() {#}
{# var csrf = $("input[name='csrfmiddlewaretoken']").val();#}
{# var user = $("#user").val();#}
{# $.ajax({#}
{# url: '/csrf_test.html/',#}
{# type: 'POST',#}
{# data: {"user": user, "csrfmiddlewaretoken": csrf},#}
{# success: function (arg) {#}
{# console.log(arg);#}
{# }#}
{# })#}
{# }#}
{#</script>#} {#csrf数据放于请求头中#}
<script>
function submitForm() {
var csrf = $.cookie('csrftoken');
var user = $("#user").val();
$.ajax({
url: '/csrf_test.html/',
type: 'POST',
headers: {'X-CSRFToken': csrf},
data: {"user": user},
success: function (arg) {
console.log(arg);
}
})
}
</script> </body>
</html>
Ajax重写csrf_test.html,csrf数据存放于headers中
注意:{% csrf_token %}和cookie中的csrftoken值不一样。
form表单中的隐藏csrf_token

cookie中

参考资料:
1. http://www.cnblogs.com/wupeiqi/articles/5246483.html
Django—XSS及CSRF的更多相关文章
- [oldboy-django][2深入django]xss攻击 + csrf
1 xss攻击 xss攻击(跨站脚本攻击,用户页面提交数据来盗取cookie) - 慎用safe, 和mark_safe -- 如果要用,必须要过滤 - 定义: 用户提交内容,在页面展示用html显示 ...
- 第三百九十二节,Django+Xadmin打造上线标准的在线教育平台—sql注入攻击,xss攻击,csrf攻击
第三百九十二节,Django+Xadmin打造上线标准的在线教育平台—sql注入攻击,xss攻击,csrf攻击 sql注入攻击 也就是黑客通过表单提交的地方,在表单里输入了sql语句,就是通过SQL语 ...
- Django是如何防止注入攻击-XSS攻击-CSRF攻击
注入攻击-XSS攻击-CSRF攻击介绍请访问:https://www.cnblogs.com/hwnzy/p/11219475.html Django防止注入攻击 Django提供一个抽象的模型层来组 ...
- XSS攻击&CSRF攻击 ----Django解决方案
XSS攻击: XSS又叫CSS (Cross Site Script) ,跨站脚本攻击.它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执 ...
- XSS与CSRF两种跨站攻击比较
XSS:跨站脚本(Cross-site scripting) CSRF:跨站请求伪造(Cross-site request forgery) 在那个年代,大家一般用拼接字符串的方式来构造动态SQL 语 ...
- 【实习记】2014-08-23网络安全XSS与CSRF总结
XSS:脚本中的不速之客XSS:跨站脚本(Cross-site scripting)CSRF:冒充用户之手CSRF:跨站请求伪造(Cross-site request forgery) 谷歌搜 ...
- 总结 XSS 与 CSRF 两种跨站攻击
前言 在那个年代,大家一般用拼接字符串的方式来构造动态 SQL 语句创建应用,于是 SQL 注入成了很流行的攻击方式.在这个年代, 参数化查询 [1] 已经成了普遍用法,我们已经离 SQL 注入很远了 ...
- 总结XSS与CSRF两种跨站攻击
XSS:跨站脚本(Cross-site scripting),实际应是"CSS",但由于和层叠样式表CSS名称冲突,故改为"XSS" CSRF:跨站请求伪造(C ...
- XSS与CSRF两种跨站攻击总结
在那个年代,大家一般用拼接字符串的方式来构造动态 SQL 语句创建应用,于是 SQL 注入成了很流行的攻击方式.在这个年代, 参数化查询 [1] 已经成了普遍用法,我们已经离 SQL 注入很远了.但是 ...
随机推荐
- excel2010冻结行列
https://jingyan.baidu.com/article/a24b33cd56f6bd19ff002b7c.html
- 查看已安装tensorflow版本以及安装路径
查看版本: import tensorflow as tf tf.__version__ 查看安装路径: tf.__path__
- [转载] 第三篇:数据仓库系统的实现与使用(含OLAP重点讲解)
阅读目录 前言 创建数据仓库 ETL:抽取.转换.加载 OLAP/BI工具 数据立方体(Data Cube) OLAP的架构模式 小结 回到顶部 前言 上一篇重点讲解了数据仓库建模,它是数据仓库开发中 ...
- java 上传文件大小转换为 GB/MB/KB/B
1.工具类 package cn.cmodes.common.utils; import java.io.File; import java.io.FileInputStream; import ja ...
- 高阶篇:4.1.2.2)产品部件级别的QFDII
本章目的:介绍产品部件级别的QFDII编写方法. 1.前言 这章接前面总成级别的QFDII. 产品部件级别的QFDII,其实就是将部件QFDII所得到的设计要求,进一步分配给部件其装配层级的零部件中. ...
- Android Notification 的四种使用方式
实现通知步骤 一般实现通知需要如下步骤: 1.获取 NotificationManager 实例管理通知: 2.实例 Notification 对象: 3.管理事件 Intent: 4.发送通知. 注 ...
- Docker搭建tomcat运行环境(Dockerfile方式)
上一篇文章的基本做法是通过centOS的官方镜像启动一个容器,然后进入到容器中,手动敲命令安装JDK跟tomcat,这个跟在linux下搭建没有什么区别,只是用来熟悉docker命令,并且在日常开发中 ...
- springboot整合spring data jpa 动态查询
Spring Data JPA虽然大大的简化了持久层的开发,但是在实际开发中,很多地方都需要高级动态查询,在实现动态查询时我们需要用到Criteria API,主要是以下三个: 1.Criteria ...
- Asp.Net webconfig中使用configSections的用法
最近闲来无事,研究研究公司的框架,无意中打开了webconfig页面,发现了一个我不认识的节点<configSections></configSections>,于是百度之,大 ...
- 设计模式之第7章-外观模式(Java实现)
设计模式之第7章-外观模式(Java实现) “鱼哥,知道怎么把大象装进冰箱里面么?”(作者按:这么简单的问题还想考我,早了几百年吧.)“把大象装进冰箱里,一共需要三步:第一步,把冰箱门打开:第二步,把 ...