CSRF攻击原理图
可以从数字签名的角度理解csrf_token
例子
models.py
from django.db import models
# Create your models here.
class User(models.Model):
username = models.CharField(max_length=16)
password = models.CharField(max_length=16)
#urls.py
from django.urls import path,re_path
from . import views
urlpatterns = [
path('',views.index_handler,name='index'),
re_path('set_cookie/(.+)/(.+)',views.set_cookie_handler,name='set_cookie'),
re_path('get_cookie/(.+)',views.get_cookie_handler,name='get_cookie'),
re_path('set_session/(.+)/(.+)',views.set_session_handler,name='set_session'),
re_path('get_session/(.+)',views.get_session_handler,name='get_session'),
path('flush',views.flush_session_handler,name='flush'),
path('clear',views.clear_session_handler,name='clear'),
path('form',views.form_handler,name='form'),
path('form_get',views.form_get_handler,name='form_get'),
path('form_post',views.form_post_handler,name='form_post'),
path('register',views.register_handler,name='register'),
]
#views.py
from django.shortcuts import render,HttpResponse
from user.models import User
# Create your views here.
def index_handler(request):
return HttpResponse('index')
def set_cookie_handler(request,key,value):
response = HttpResponse()
response.set_cookie(key,value,max_age=60*60)
return response
def get_cookie_handler(request,key):
value = request.COOKIES.get(key)
return HttpResponse(value)
def set_session_handler(request,key,value):
request.session[key] = value
# request.session.set_expiry(60*60)
return HttpResponse('设置成功')
def get_session_handler(request,key):
value = request.session.get(key)
return HttpResponse(value)
def flush_session_handler(request):
request.session.flush()
return HttpResponse('flush')
def clear_session_handler(request):
request.session.clear()
return HttpResponse('clear')
def form_handler(request):
return render(request,'form.html')
def form_get_handler(request):
username = request.GET.get('username')
hobbys = request.GET.getlist('hobby')
print('username:',username)
print('hobbys',hobbys)
return HttpResponse('')
def form_post_handler(request):
username = request.POST.get('username')
hobbys = request.POST.getlist('hobby')
print('username:',username)
print('hobbys',hobbys)
return HttpResponse('')
def register_handler(request):
if request.method == 'GET':
return render(request,'register.html')
else:
username = request.POST.get('username')
password = request.POST.get('password')
# user = User()
# user.username = username
# user.password = password
# user.save()
User(username=username,password=password).save()
return HttpResponse('注册成功')
{#register.html#}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="{% url 'register' %}" method="post">
{% csrf_token %}
username
<input type="text" name="username"><br/>
password
<input type="password" name="password"><br/>
<input type="submit" value="submit">
</form>
</body>
</html>
运行manage.py(有CSRF中间件)
输入:http://127.0.0.1:8000/register
输入并提交
数据库中:
攻击
1、取消CSRF:
setting.py
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'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',
]
编写diaoyu.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="http://127.0.0.1:8000/register" method="post">
username
<input type="text" name="username"><br/>
password
<input type="password" name="password"><br/>
<input type="submit" value="submit">
</form>
</body>
</html>
运行这个html文件
输入并提交:
数据库中:
也存在这条数据,这就是CSRF跨域攻击
防范
将setting.py中的中间件取消注释
重新运行manage.py
回到上个页面,输入并提交:
会出现403错误,这就是CSRF攻击的防范