一,csrf攻擊
- 這是我們本身的功能
1,已經(jīng)實現(xiàn)必須登錄才可以進(jìn)行其他操作
登錄裝飾器:
def login_require(view_func):
"""實現(xiàn)登錄裝飾器"""
def wrapper(request, *args, **kwargs):
if 'login_status' in request.session and request.session['login_status']:
return view_func(request, *args, **kwargs)
else:
return redirect('/login')
return wrapper
2,實現(xiàn)一個修改密碼的功能,用裝飾器使必須登錄才能進(jìn)行修改密碼操作
view.py
@login_require
def change_pwd(request):
if request.method == 'POST':
pwd = request.POST.get('pwd')
return HttpResponse("修改密碼成功為:" + pwd)
else:
return render(request, 'llhtestapp/change_pwd.html')
change_pwd.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>修改密碼</title>
</head>
<body>
<h3>修改密碼</h3>
<form method="post" action="/change_pwd">
<p>密碼:</p><input type="password" name="pwd">
<p></p><input type="submit" value="確認(rèn)修改">
</form>
</body>
</html>
url配置:
url(r'^change_pwd', views.change_pwd),
3,先注銷了django.middleware.csrf.CsrfViewMiddleware的中間件
4,我們現(xiàn)在登錄成功,但是沒有準(zhǔn)備改密碼(服務(wù)運行在2345端口上)
- 現(xiàn)在來進(jìn)行csrf攻擊
1,我們在另一個項目寫了一個index頁面
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<h1>這是index頁面</h1>
<form method="post" action="http://127.0.0.1:2345/change_pwd">
<input type="hidden" name="pwd" value="999">
<input type="submit" value="點擊一下試試">
</form>
</body>
</html>
view.py
def index(request):
return render(request, 'llhtestapp02/index.html')
url配置
url(r'^index', views.index),
2,現(xiàn)在我們把這個服務(wù)起在另一個端口或者另一個能互通的機器上
3,在相同瀏覽器訪問這個服務(wù)的index頁
4,點擊一下這個按鈕
二, 如何防護(hù)
1,打開csrf防護(hù)
2,在post表單加上{% csrf_token %}
3,再試試點擊
4,我們試試用本項目的服務(wù)修改密碼
三,防御原理
1,渲染模板文件時在頁面生成一個叫csfrmiddlewaretoken的隱藏域
2,服務(wù)器提交給瀏覽器保存一個名字為csfrtoken的cookie信息
3,提交表單是,兩個值都會發(fā)給服務(wù)器,服務(wù)器進(jìn)行比對,如果一樣,則csrf驗證通過,否則失效