18_CSRF_TOKEN跨站请求伪造

2018-11-23  本文已影响0人  knot98

CSRF_TOKEN跨站请求伪造

一、CSRF是什么

攻击者盗用了你的身份,以你的名义发送恶意请求,但对服务器来说这个请求是完全合法的

二、CSRF攻击原理

如下图:
19_CSRF.png
从上图可以看出,要完成一次CSRF攻击,受害者必须依次完成两个步骤:

1.登录受信任网站A,并在本地生成Cookie。

2.在不登出A的情况下,访问危险网站B。

看到这里,你也许会说:“如果我不满足以上两个条件中的一个,我就不会受到CSRF的攻击”。是的,确实如此,但你不能保证以下情况不会发生:

1.你不能保证你登录了一个网站后,不再打开一个tab页面并访问另外的网站。

2.你不能保证你关闭浏览器了后,你本地的Cookie立刻过期,你上次的会话已经结束。(事实上,关闭浏览器不能结束一个会话,但大多数人都会错误的认为关闭浏览器就等于退出登录/结束会话了......)

3.上图中所谓的攻击网站,可能是一个存在其他漏洞的可信任的经常被人访问的网站。

三、CSRF攻击防范

目前防御 CSRF 攻击主要有三种策略:验证 HTTP Referer 字段;在请求地址中添加 token 并验证;在 HTTP 头中自定义属性并验证

四、CSRF的简单使用

方法一:在form表单中应用:
<form action="" method="post">
    {% csrf_token %}
    <p>用户名:<input type="text" name="name"></p>
    <p>密码:<input type="text" name="password"></p>
    <p><input type="submit"></p>
</form>
方法二:在AJAX中
放在data里:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="/static/jquery-3.3.1.js"></script>
    <title>Title</title>
</head>
<body>
<form action="" method="post">
    {% csrf_token %}
    <p>用户名:<input type="text" name="name"></p>
    <p>密码:<input type="text" name="password" id="pwd"></p>
    <p><input type="submit"></p>
</form>
<button class="btn">点我</button>
</body>
<script>
    $(".btn").click(function () {
        $.ajax({
            url: '',
            type: 'post',
            data: {
                'name': $('[name="name"]').val(),
                'password': $("#pwd").val(),
                'csrfmiddlewaretoken': $('[name="csrfmiddlewaretoken"]').val()
            },
            success: function (data) {
                console.log(data)
            }

        })
    })
</script>
</html>
放在cookie里:

五、CSRF的全站禁用、局部使用以及局部禁用

全站禁用:在settings.py文件中注释掉中间件中的:

'django.middleware.csrf.CsrfViewMiddleware',

局部禁用:用装饰器(在FBV中使用)
from django.views.decorators.csrf import csrf_exempt,csrf_protect
# 不再检测,局部禁用(前提是全站使用)
# @csrf_exempt
# 检测,局部使用(前提是全站禁用)
# @csrf_protect
def csrf_token(request):
    if request.method=='POST':
        print(request.POST)

        return HttpResponse('ok')
    return render(request,'csrf_token.html')
在CBV中使用:
# 需要导入特定的装饰器装饰一下,局部禁用、局部使用的装饰器
from django.views import View
from django.views.decorators.csrf import csrf_exempt,csrf_protect
from django.utils.decorators import method_decorator

# CBV的csrf装饰器,只能加载类上(指定方法为dispatch)和dispatch方法上

@method_decorator(csrf_exempt,name='dispatch')
class Foo(View):
    
    # @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        return super(HomeView, self).dispatch(request, *args, **kwargs)

    def get(self,request):
        pass
    
    def post(self,request):
        pass
    
上一篇 下一篇

猜你喜欢

热点阅读