CSRFXSSclickjackingSQL 的攻击与防御
Posted F·灬疯子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CSRFXSSclickjackingSQL 的攻击与防御相关的知识,希望对你有一定的参考价值。
CSRF攻击
原理:
跨站请求伪造。是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。
网站通过cookie来实现登录功能。而cookie只要存在浏览器中,那么浏览器在访问含有这个cookie的服务器的时候,会自动的携带cookie信息到服务器上去。就会存在一个漏洞:当你访问了一个病毒网站时,该网站可以在网页源代码中插入js代码,使用js代码给其他服务器发送请求(如ICBC的转账请求)。因为在发送请求的时候,浏览器会自动的把cookie发送给对应的服务器,这时候相应的服务器(如ICBC网站)不知道这个请求是伪造的,就被欺骗过去了。从而达到在用户不知情的情况下,给某个服务器发送了一个请求(比如转账)。
iframe:
- 可以加载嵌入别的域名下的网页。即可以发送跨域请求。
- 因为iframe加载的是别的域名下的网页。根据同源策略,js只能操作属于本域名下的代码,因此js不能操作通过iframe加载来的DOM元素。
- 如果ifrmae的src属性为空,那么就没有同源策略的限制,这时候可以操作iframe下面的代码了。并且,如果src为空,那么可以在iframe中,给任何域名都可以发送请求。
- 直接在iframe中写html代码,浏览器是不会加载的。
可利用iframe的功能对网站进行攻击
例:银行网站的转账相关简易代码
1 # 转账 2 # 登录后,进行转账时确认转账用户的邮箱及转账金额; 3 @method_decorator(login_required,name=‘dispatch‘) 4 class TransferView(View): 5 def get(self,request): 6 return render(request,‘transfer.html‘) 7 8 def post(self,request): 9 form = TransferForm(request.POST) 10 if form.is_valid(): 11 email = form.cleaned_data.get(‘email‘) 12 money = form.cleaned_data.get(‘money‘) 13 # 验证是否有session信息 14 user = request.front_user 15 if user.balance >= money: 16 User.objects.filter(email=email).update(balance=F(‘balance‘)+money) 17 # 当前用户; 18 user.balance -= money 19 user.save() 20 return HttpResponse(‘转账成功!‘) 21 else: 22 return HttpResponse(‘余额不足!‘) 23 else: 24 print(form.errors) 25 return redirect(reverse(‘transfer‘))
攻击方的代码:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>首页</title> 6 <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script> 7 </head> 8 <body> 9 <!--用户看到的界面图片--> 10 <img src="http://cms-bucket.nosdn.127.net/312e057a25f148519dc02b40812c78fe20170510155251.gif" alt="" width="100%" height="100%"> 11 12 <!--使用iframe,src不加载网页,为空可给任何域名发送请求,添加id的值获取HTML代码--> 13 <iframe id="stealframe" src="" frameborder="0" style="width:0;height:0;"> 14 </iframe> 15 <div id="box" style="width: 0;height: 0;"> 16 <form action="http://127.0.0.1:8000/transfer/" method="post" id="myform"> 17 <input type="text" name="email" value="[email protected]"> 18 <input type="text" name="money" value="100"> 19 </form> 20 </div> 21 <script> 22 //获取html=myform的代码 23 window.onload = function () { 24 $(‘#stealframe‘).contents().find(‘html‘).html($(‘#myform‘)); 25 //自动提交代码 26 $(‘#stealframe‘).contents().find(‘html‘).children(‘#myform‘).submit(); 27 } 28 </script> 29 </body> 30 </html>
每运行一次攻击者网站,内部将提交一遍 id=form 的html代码, iframe 设置其为不加载该HTML网页但进行网页内部的请求操作。
防御CSRF攻击
CSRF攻击的要点就是在向服务器发送请求的时候,相应的cookie会自动的发送给对应的服务器。造成服务器不知道这个请求是用户发起的还是伪造的。这时候,可以在用户每次访问有表单的页面的时候,在网页源代码中加一个随机的字符串叫做 csrf_token ,在cookie中也加入一个相同值的 csrf_token 字符串。以后给服务器发送请求的时候,服务器只有检测到cookie中和网页body中的 csrf_token 都相同,才认为这个请求是正常的,否则就是伪造的。
在Django中防御CSRF攻击:
- settings.MIDDLEWARE中添加 CsrfMiddleware 中间件。
- 在模版代码中添加一个input标签,加载 csrf_token 。
- 模版中添加代码: <input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}"/>
-
- 或直接使用‘csrf_token标签’,来自动生成一个带有 csrf token 的‘input标签’: {% csrf_token %}
使用ajax处理csrf防御:
用ajax来处理csrf防御,需要手动的在form中添加csrfmiddlewaretoken,或者是在请求头中添加 X-CSRFToken 。我们可以从返回的cookie中提取csrf token,再设置进去。
1 //static:myajax.js 2 function getCookie(name) { 3 var cookieValue = null; 4 if (document.cookie && document.cookie !== ‘‘) { 5 var cookies = document.cookie.split(‘;‘); 6 for (var i = 0; i < cookies.length; i++) { 7 var cookie = jQuery.trim(cookies[i]); 8 // Does this cookie string begin with the name we want? 9 if (cookie.substring(0, name.length + 1) === (name + ‘=‘)) { 10 cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); 11 break; 12 } 13 } 14 } 15 return cookieValue; 16 } 17 18 var myajax = { 19 ‘get‘: function (args) { 20 args[‘method‘] = ‘get‘; 21 this.ajax(args); 22 }, 23 ‘post‘: function (args) { 24 args[‘method‘] = ‘post‘; 25 this._ajaxSetup(); 26 this.ajax(args); 27 }, 28 ‘ajax‘: function (args) { 29 $.ajax(args); 30 }, 31 ‘_ajaxSetup‘: function () { 32 $.ajaxSetup({ 33 beforeSend: function(xhr, settings) { 34 if (!/^(GET|HEAD|OPTIONS|TRACE)$/.test(settings.type) && !this.crossDomain) { 35 xhr.setRequestHeader("X-CSRFToken", getCookie(‘csrftoken‘)); 36 } 37 } 38 }); 39 } 40 };
在模板中导入:
1 {% load static %} 2 <!DOCTYPE html> 3 <html lang="en"> 4 <head> 5 <meta charset="UTF-8"> 6 <title>中国工商银行-转账</title> 7 <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script> 8 <script src="{% static ‘myajax.js‘ %}"></script> 9 <script> 10 $(function () { 11 $("#submit").click(function (event) { 12 event.preventDefault(); 13 var email = $("input[name=‘email‘]").val(); 14 var money = $("input[name=‘money‘]").val(); 15 16 myajax.post({ 17 ‘url‘: ‘/transfer/‘, 18 ‘data‘: { 19 ‘email‘: email, 20 ‘money‘: money 21 }, 22 ‘success‘: function (data) { 23 // 如果状态码是等于200才会走到success的回调中 24 console.log(data); 25 }, 26 ‘fail‘: function (error) { 27 console.log(error); 28 } 29 }); 30 }); 31 }); 32 </script> 33 </head> 34 --snip--
XSS攻击:
跨站脚本攻击。是一种网站应用程序的安全漏洞攻击,是代码注入的一种,利用网页开发时留下的漏洞,注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。
比如A网站有一个发布帖子的入口,如果用户在提交数据的时候,提交了一段js代码 <script>alert("hello world");</script> ,然后A网站在渲染这个帖子的时候,直接把这个代码渲染了,那么这个代码就会执行,会在浏览器的窗口中弹出一个模态对话框来显示 hello world! ,攻击者可利用该漏洞进行攻击。
<li><script>alert("Hello world")</script></li>
防御:
- 如果不需要显示一些富文本,那么在渲染用户提交的数据的时候,直接进行转义。在Django的模板中默认就是转义的。也可以把数据在存储到数据库之前,先转义再存储进去,这样以后在渲染的时候,即使不转义也不会有安全问题。
1 # 使用escape在存储前先进行转义 2 @require_http_methods([‘POST‘]) 3 def add_comment(request): 4 content = request.POST.get(‘content‘) 5 content = escape(content) 6 Comment.objects.create(content=content) 7 return redirect(reverse(‘index‘))
- 如果对于用户提交上来的数据包含了一些富文本(比如:给字体换色,字体加粗等),在渲染的时候也要以富文本的形式进行渲染,也即需要使用 safe过滤器 将其标记为安全的,这样才能显示出富文本样式,但标签全通过会有安全隐患。所以可以使用 bleach库 的 sanitizer ,在服务器处理数据的时候,将需要的标签保留下来,把那些不需要的标签进行转义或者移除掉。
1 <!--html模板代码--> 2 <!--safe会通过所有的标签--> 3 {% for comment in comments %} 4 <li>{{ comment.content | safe}}</li> 5 {% endfor %}
1 # 使用bleach库 2 3 from django.shortcuts import render,redirect,reverse 4 from .models import Comment 5 from django.views.decorators.http import require_http_methods 6 from django.template.defaultfilters import escape 7 import bleach 8 from bleach.sanitizer import ALLOWED_TAGS,ALLOWED_ATTRIBUTES 9 10 # 首页,显示出数据库中comments所有的值, 11 def index(request): 12 context = { 13 ‘comments‘:Comment.objects.all() 14 } 15 return render(request,‘index.html‘,context=context) 16 17 # 将提交的数据保存并返回首页 18 @require_http_methods([‘POST‘]) 19 def add_comment(request): 20 content = request.POST.get(‘content‘) 21 # 在bleach库已默认允许通过的标签、属性上再添加需要的新标签及属性 22 tags = ALLOWED_TAGS + [‘img‘] 23 attributes = {**ALLOWED_ATTRIBUTES,‘img‘:[‘src‘]} 24 # 对提交的数据进行过滤 25 cleaned_data = bleach.clean(content,tags=tags,attributes=attributes) 26 Comment.objects.create(content=cleaned_data) 27 return redirect(reverse(‘index‘))
bleach库:
- tags:表示允许哪些标签。
- attributes:表示标签中允许哪些属性。
- ALLOWED_TAGS:默认定义的一些标签。如果不符合要求,可以对其进行增加或者删除。
- ALLOWED_ATTRIBUTES:默认定义的一些属性。如果不符合要求,可以对其进行增加或者删除。
clickjacking攻击:
又称作点击劫持攻击。是一种在网页中将恶意代码等隐藏在看似无害的内容(如按钮)之下,并诱使用户点击的手段。
两种攻击方式:
- 攻击者使用一个透明的iframe,覆盖在一个网页上,然后使用户在该页面上进行操作,如网页包含了一个按钮A,按钮上面浮了一个透明的iframe标签,用户将在不知情的情况下点击透明的iframe页面进行加载。
- 攻击者使用一张图片覆盖在网页,遮挡网页原有位置的含义;如用户收到一封包含一段视频的电子邮件,但其中的“播放”按钮并不会真正播放视频,而是链入一购物网站。这样当用户试图“播放视频”时,实际是被诱骗而进入了一个购物网站。
1 # clickjacking攻击 2 def index(request): 3 return render(request,‘clickjacking.html‘)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>点击劫持</title> 6 <style> 7 iframe{ 8 width:100%; 9 height:100%; 10 display:block; 11 position: absolute; 12 z-index: 2; 13 opacity: 0.01; 14 } 15 button{ 16 position: absolute; 17 top: 45px; 18 left: 180px; 19 z-index: 1; 20 } 21 </style> 22 </head> 23 <body> 24 点击下方的按钮将会进行跳转: 25 <button>跳转按钮</button> 26 <iframe src="https://www.bilibili.com/video/av21663728/?p=33" frameborder="0"></iframe> 27 </body> 28 </html>
z-index :设置元素的堆叠顺序。拥有更高堆叠顺序的元素总是会处于堆叠顺序较低的元素的前面。
position: 规定元素的定位类型。
opacity :设置元素的不透明级别。
clickjacking防御:
设置网站不允许使用iframe被加载到其他网页中,就可以避免这种攻击。可以通过在响应头中设置 X-Frame-Options 来设置这种操作。
X-Frame-Options 可设置的值:
- DENY:不让任何网页使用iframe加载该页面。
- SAMEORIGIN:只允许在相同域名(即本人的网站)下使用iframe加载该页面。
- ALLOW-FROM origin:允许任何网页通过iframe加载该网页。
在Django中可使用中间件 django.middleware.clickjacking.XFrameOptionsMiddleware ,这个中间件设置了“X-Frame-Option”为 SAMEORIGIN ,即在同域名的网站下才可以使用iframe加载这个网页,可避免被攻击者通过iframe去加载了。
SQL注入
通过把SQL命令插入到表单中或页面请求的查询字符串中,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。 比如先前的很多影视网站泄露VIP会员密码大多就是通过WEB表单递交查询字符暴出的。
以上是关于CSRFXSSclickjackingSQL 的攻击与防御的主要内容,如果未能解决你的问题,请参考以下文章