CSRF攻击概述
CSRF(Cross Site Request Forgery, 跨站域请求伪造)是一种网络的攻击方式,它在 2007 年曾被列为互联网 20 大安全隐患之一。其他安全隐患,比如 SQL 脚本注入,跨站域脚本攻击等在近年来已经逐渐为众人熟知,很多网站也都针对他们进行了防御。然而,对于大多数人来说,CSRF 却依然是一个陌生的概念。即便是大名鼎鼎的 Gmail, 在 2007 年底也存在着 CSRF 漏洞,从而被黑客攻击而使 Gmail 的用户造成巨大的损失。
CSRF攻击原理
cookiecookiecookiecookiecookie
防御CSRF攻击
cookiecsrf_tokencookiecsrf_tokenbodycookiecsrf_tokencookiecsrf_tokenbodycsrf_tokenDjangoCSRFsettings.MIDDLEWARECsrfMiddlewareinputcsrf_token
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.middleware.gzip.GZipMiddleware',
'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'
]
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}"/>
{% csrf_token %}
使用ajax处理csrf防御
ajaxcsrfformcsrfmiddlewaretokenX-CSRFTokencookiecsrf token
function getCookie(name) {
var cookieValue = 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 begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var myajax = {
'get': function (args) {
args['method'] = 'get';
this.ajax(args);
},
'post': function (args) {
args['method'] = 'post';
this._ajaxSetup();
this.ajax(args);
},
'ajax': function (args) {
$.ajax(args);
},
'_ajaxSetup': function () {
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!/^(GET|HEAD|OPTIONS|TRACE)$/.test(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
}
}
});
}
};
$(function () {
$("#submit").click(function (event) {
event.preventDefault();
var email = $("input[name='email']").val();
var money = $("input[name='money']").val();
myajax.post({
'url': '/transfer/',
'data':{
'email': email,
'money': money
},
'success': function (data) {
console.log(data);
},
'fail': function (error) {
console.log(error);
}
});
})
});
iframe相关知识
<iframe src="http://www.baidu.com/">
</ifrmae>
XSS攻击 XSS
XSS攻击场景
A网站jsA网站hello worldjs
XSS攻击防御
from django.template.defaultfilters import escape
from .models import Comment
from django.http import HttpResponse
def comment(request):
content = request.POST.get("content")
escaped_content = escape(content)
Comment.objects.create(content=escaped_content)
return HttpResponse('success')
# views.py
def index(request):
message = "<span style='color:red;'>红色字体</span><script>alert('hello world');</script>";
return render_template(request,'index.html',context={"message":message})
# index.html
bleach库
bleachhtml
pip install bleach
bleach.cleanbleach.clean
import bleach
from bleach.sanitizer import ALLOWED_TAGS,ALLOWED_ATTRIBUTES
@require_http_methods(['POST'])
def message(request):
# 从客户端中获取提交的数据
content = request.POST.get('content')
# 在默认的允许标签中添加img标签
tags = ALLOWED_TAGS + ['img']
# 在默认的允许属性中添加src属性
attributes = {**ALLOWED_ATTRIBUTES,'img':['src']}
# 对提交的数据进行过滤
cleaned_content=bleach.clean(content,tags=tags,attributes=attributes)
# 保存到数据库中
Message.objects.create(content=cleaned_content)
return redirect(reverse('index'))
相关介绍如下:
tagsattributesALLOWED_TAGSbleachALLOWED_ATTRIBUTESbleach
bleach更多资料
clickjacking(点击劫持)攻击clickjacking
clickjacking攻击场景
场景一
如用户收到一封包含一段视频的电子邮件,但其中的“播放”按钮并不会真正播放视频,而是链入一购物网站。这样当用户试图“播放视频”时,实际是被诱骗而进入了一个购物网站。
场景二
按钮Aiframeiframe按钮A按钮Aiframe
<!DOCTYPE html>
<html>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<head>
<title>点击劫持</title>
<style>
iframe{
opacity:0.01;
position:absolute;
z-index:2;
100%;
height: 100%;
}
button{
position:absolute;
top: 345px;
left: 630px;
z-index: 1;
72px;
height: 26px;
}
</style>
</head>
<body>
这个合影里面怎么会有你?
<button>查看详情</button>
<iframe src="http://tieba.baidu.com/f?kw=%C3%C0%C5%AE"></iframe>
</body>
</html>
页面看起来比较简陋,但是实际上可能会比这些更精致一些。当这个页面通过某种手段被传播出去后,用户如果点击了“查看详情”,实际上点击到的是关注的按钮,这样就可以增加了一个粉丝。
clickjacking防御
iframeX-Frame-OptionsX-Frame-Options
DENYiframeSAMEORIGINiframeALLOW-FROM originiframe
Djangodjango.middleware.clickjacking.XFrameOptionsMiddlewareX-Frame-OptionSAMEORIGINiframeiframe
SQL注入 所谓SQL注入,就是通过把SQL命令插入到表单中或页面请求的查询字符串中,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。 比如先前的很多影视网站泄露VIP会员密码大多就是通过WEB表单递交查询字符暴出的。
场景
front_user
class User(models.Model):
telephone = models.CharField(max_length=11)
username = models.CharField(max_length=100)
password = models.CharField(max_length=100)
sql
def index(request):
user_id = request.GET.get('user_id')
cursor = connection.cursor()
cursor.execute("select id,username from front_user where id=%s" % user_id)
rows = cursor.fetchall()
for row in rows:
print(row)
return HttpResponse('success')
select id,username from front_user where id=1 or 1=1
def index(request):
username = request.GET.get('username')
cursor = connection.cursor()
cursor.execute("select id,username from front_user where username='%s'" % username)
rows = cursor.fetchall()
for row in rows:
print(row)
return HttpResponse('success')
select id,username from front_user where username='zhiliao' or '1=1'
sql注入防御
sqlsqlsqlsql
def index(request):
user_id = "1 or 1=1"
cursor = connection.cursor()
cursor.execute("select id,username from front_user where id=%s",(user_id,))
rows = cursor.fetchall()
for row in rows:
print(row)
return HttpResponse('success')
sql
ORMORMsqlsql