Django—XSS及CSRF
綜合編程 Python_博客園 (源鏈) 2017-06-28
一、XSS
跨站腳本攻擊 (Cross Site Scripting),為不和 層疊樣式表 (Cascading Style Sheets, CSS )的縮寫混淆,故將跨站腳本攻擊縮寫為XSS。惡意攻擊者往Web頁面裏插入惡意Script代碼,當用戶瀏覽該頁之時,嵌入其中Web裏面的Script代碼會被執行,從而達到惡意攻擊用戶的目的。
1. 工作流程
a. 惡意用戶,在一些公共區域(例如,建議提交表單或消息公共板的輸入表單)輸入一些文本,這些文本被其它用戶看到,但這些文本不僅僅是他們要輸入的文本,同時還包括一些可以在客戶端執行的腳本。如:
this.document = "*********";
alert(‘Not Safe‘);
b. 惡意提交這個表單
c. 其他用戶看到這個包括惡意腳本的頁面並執行,獲取用戶的cookie等敏感信息。
2. 實例-未防範XSS攻擊
1 pinglu = [] # 評論列表
2
3 #提交表單
4 def commit(request):
5 if request.method == ‘GET‘:
6 return render(request, ‘commit.html‘)
7 else:
8 com = request.POST.get(‘commit‘)
9 pinglu.append(com)
10 return redirect(‘/index.html/‘)
11
12
13 #查看評論頁面
14 def index(request):
15 return render(request, ‘index.html‘, {‘commit‘: pinglu})
view.py
1
2
3
4
5
6
7
8
評論
9
1
2
3
4
5
6
7
8
評論
9 {% for item in commit %}
10
{{ item|safe }}
11 {# item後加safe,默認數據安全,django不會做特殊處理#}
12 {% endfor %}
13
14
index.html
以上實例中,若在commit.html頁面輸入以下內容並提交:
alert(123)
則會在index頁面執行此行代碼,彈出警告框(若包含惡意代碼,則會執行)
3. 防範XSS攻擊
- 最直接的方法就是對於無法控制的輸入在html頁面內不要使用safe
{#
{{ item|safe }}
#}
{{ item }}
- 也可以在views裏進行過濾,防止特殊字符提交到數據庫或網頁內
def commit(request):
if request.method == ‘GET‘:
return render(request, ‘commit.html‘)
else:
com = request.POST.get(‘commit‘)
if ‘‘ in com: # 過濾“”關鍵字,防止惡意代碼的提交
return render(request, ‘commit.html‘, {‘error‘: ‘此條評論有毒,已被和諧‘})
else:
pinglu.append(com)
return redirect(‘/index.html/‘)
二、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‘,
1 from django.shortcuts import render, HttpResponse, redirect
2
3 def csrf_test(request):
4 if request.method == ‘GET‘:
5 return render(request, ‘csrf_test.html‘)
6 else:
7 return HttpResponse(‘ok‘)
views.py
1
2
3
4
5
6
7
8
修改csef_test.html:
1
2
3
4
5
6
7
8
- 全站禁用,即將settings.py中的 ‘django.middleware.csrf.CsrfViewMiddleware’ 註釋掉即可
- 基於FBV視圖的局部禁用和使用
1 #settings.py
2 #啟用 ‘django.middleware.csrf.CsrfViewMiddleware‘,
3
4
5 from django.views.decorators.csrf import csrf_exempt
6
7
8 @csrf_exempt
9 def csrf_test(request):
10 if request.method == ‘GET‘:
11 return render(request, ‘csrf_test.html‘)
12 else:
13 return HttpResponse(‘ok‘)
局部禁用
1 #settings.py
2 #禁用 #‘django.middleware.csrf.CsrfViewMiddleware‘,
3
4
5 from django.views.decorators.csrf import csrf_protect
6
7
8 @csrf_protect
9 def csrf_test(request):
10 if request.method == ‘GET‘:
11 return render(request, ‘csrf_test.html‘)
12 else:
13 return HttpResponse(‘ok‘)
局部使用
- 基於CBV視圖的(只能局部使用或禁用類,不能在類方法裏局部使用或禁用
1 #settings.py
2 #禁用 ‘django.middleware.csrf.CsrfViewMiddleware‘,
3
4
5 from django.views import View
6 from django.views.decorators.csrf import csrf_protect
7 from django.utils.decorators import method_decorator
8
9
10 @method_decorator(csrf_protect, name=‘dispatch‘)
11 class Foo(View):
12 def get(self, request):
13 pass
14
15 def post(self, request):
16 pass
局部使用
1 #settings.py
2 #啟用 ‘django.middleware.csrf.CsrfViewMiddleware‘,
3
4
5 from django.views import View
6 from django.views.decorators.csrf import csrf_exempt
7 from django.utils.decorators import method_decorator
8
9
10 @method_decorator(csrf_exempt, name=‘dispatch‘)
11 class Foo(View):
12 def get(self, request):
13 pass
14
15 def post(self, request):
16 pass
局部禁用
- Ajax提交數據時,攜帶CSRF
1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
註意: {
%
csrf_token
%
}和cookie中的csrftoken值不一樣。
form表單中的隱藏csrf_token
cookie中
Django—XSS及CSRF