第十篇:跨站请求伪造csrf

钓鱼网站

钓鱼网站和正规网站的页面一模一样,提交网页数据的url也一样,但是会在页面中设置隐藏属性的form表单。例如转账:给用户书写的form表单,对方账号的input没有name属性,然后另外写一个具有默认的并且是隐藏的具有name属性的input框。

form表单如何通过csrf校验

为了防止此类事情的发生,我们使用csrf_token生成随机字符串

在form表单内添加:

{% csrf_token %}

browser客户端向服务端发动get请求,服务端返回给browser一串随机的字符串,当browser向服务端发送post请求时,会携带上该字符串,服务端会先对该随机字符串进行校验,如果客户端携带的字符串和服务器上的字符串一致,服务端会允许客户端提交post请求,否则会被forbidden掉。

当客户端向django服务端发送post请求,django中间件django.middleware.csrf.CsrfViewMiddleware会获取post中携带的name为“csrfmiddlewaretoken”的value是否和之前返回给客户端的value一致。

ajax如何通过csrf校验

第一种:自己手动获取

<body>
<form action="" method="post">
    {% csrf_token %}
    <p>用户名:<input type="text" name="username"></p>
    <p>密码: <input type="text" name="password"></p>
    <p><button id="d1">发送ajax请求</button></p>
</form>

<script>
    $('#d1').click(function () {
        $.ajax({
            url: '',
            type: 'post',
            data: {'username': 'jason', 'csrfmiddlewaretoken': $('input[name="csrfmiddlewaretoken"]').val()},
            success: function (data) {
                alert(data)
            }
        })

    })
</script>
</body>
</html>

第二种:利用模板语法,获取到随机字符串

<body>
<form action="" method="post">
    {% csrf_token %}
    <p>用户名:<input type="text" name="username"></p>
    <p>密码: <input type="text" name="password"></p>
    <p><button id="d1">发送ajax请求</button></p>
</form>

<script>
    $('#d1').click(function () {
        $.ajax({
            url: '',
            type: 'post',
            data: {'username': 'jason', 'csrfmiddlewaretoken': '{{ csrf_token }}'},
            success: function (data) {
                alert(data)
            }
        })

    })
</script>
</body>
</html>

第三种:通用方式,引用外部js文件,此种方法是django官网推荐的

在static文件夹下新建一个js文件(eg:myset.py)

// static/myset.py

function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}
var csrftoken = getCookie('csrftoken');
function csrfSafeMethod(method) {
  // these HTTP methods do not require CSRF protection
  return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

$.ajaxSetup({
  beforeSend: function (xhr, settings) {
    if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
      xhr.setRequestHeader("X-CSRFToken", csrftoken);
    }
  }
});

使用方法:引入csrf的js文件

<body>
<form action="" method="post">
    {% csrf_token %}
    <p>用户名:<input type="text" name="username"></p>
    <p>密码: <input type="text" name="password"></p>
    <p><button id="d1">发送ajax请求</button></p>
</form>

<!--此处引入csrf文件-->
{% load static %}
<script src="{% static 'myset.js' %}"></script>
<script>
    $('#d1').click(function () {
        $.ajax({
            url: '',
            type: 'post',
            data: {'username': 'jason''},
            success: function (data) {
                alert(data)
            }
        })

    })
</script>
</body>
</html>

# csrf相关装饰器

可以局部对csrf的校验进行更改

针对FBV

针对FBV的视图方法:

首先需要导入包:

# views.py

from django.views.decorators.csrf import csrf_exempt, csrf_protect

局部不校验csrf

当我们网站整体都检验csrf的时候,我们可以让某几个视图函数不校验,需要使用csrf_exempt模块:

# views.py

@csrf_exempt  # 不校验被装饰的函数
def func(request):
    pass

局部校验csrf

当我们网站整体都不校验csrf的时候,我们可以让某几个视图函数校验,需要使用csrf_protect模块:

# views.py

@csrf_protect  # 校验被装饰函数
def func(request):
    pass

针对CBV

针对CBV的视图方法:

针对下面的CBV的方法,我们如何做到局部修改csrf校验呢?

# views.py

from django.views import View
class MyHome(View):
    def get(self, request):
        return HttpResponse('get')

    def post(self, request):
        return HttpResponse('post')

局部校验csrf

全局不校验,单单针对局部的CBV的方法进行校验:

第一种方法:直接装饰在CBV内部的函数之上

# views.py

# 需要导入模块
from django.views.decorators.csrf import csrf_protect
from django.utils.decorators import method_decorator

class MyHome(View):

    def get(self, request):
        return HttpResponse('get')

    @method_decorator(csrf_protect)  # 使CBV中的函数被校验csrf
    def post(self, request):
        return HttpResponse('post')

第二种方法:装饰在CBV类上,指定装饰CBV类中的哪个函数

# views.py

# 需要导入模块
from django.views.decorators.csrf import csrf_protect
from django.utils.decorators import method_decorator

@method_decorator(csrf_protect, name='post')  # 指名道姓的给CBV中的函数装饰
class MyHome(View):
    def get(self, request):
        return HttpResponse('get')

    def post(self, request):
        return HttpResponse('post')

局部不校验csrf

全局校验,单单针对局部的CBV中的方法不校验:

第一种方法:直接装饰在CBV内部的函数之上

# views.py

# 需要导入模块
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator

class MyHome(View):

    def get(self, request):
        return HttpResponse('get')

    @method_decorator(csrf_exempt)  # 使CBV中函数不被校验csrf
    def post(self, request):
        return HttpResponse('post')

第二种方式:装饰在CBV类上,指定装饰CBV类中的哪个函数

# views.py

# 需要导入模块
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator

@method_decorator(csrf_exempt, name='post')  # 指名道姓的给CBV中的函数装饰
class MyHome(View):
    def get(self, request):
        return HttpResponse('get')

    def post(self, request):
        return HttpResponse('post')

给CBV中的所有函数加装饰器

我们之前看源码,发现在匹配CBV中类的方法的时候,统一由dispatch函数分发,因此我们可以重写父类中的dispatch方法,给dispatch方法加装饰器,再return出去。

这种方式,相当于对CBV中的所有函数都装饰上了,影响的是CBV中的所有函数。

from django.views.decorators.csrf import csrf_exempt, csrf_protect
from django.utils.decorators import method_decorator

# @method_decorator(csrf_exempt, name='post')  # csrf_exempt 第二种方式不行
@method_decorator(csrf_exempt, name='dispatch')  # 可以!!!
class MyHome(View):  # APIView
    # @method_decorator(csrf_protect)  # 第三种 类中所有的方法都装
    # @method_decorator(csrf_exempt)  # csrf_exempt 第三种方式可以
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request,*args,**kwargs)

    def get(self,request):
        return HttpResponse('get')
    # @method_decorator(csrf_protect)  # 第一种方式
    # @method_decorator(csrf_exempt)  # csrf_exempt 第一种方式不行
    def post(self,request):
        return HttpResponse('post')

特例:对于CBV来说,当我们打开全局校验csrf的时候,针对CBV中的某个方法不进行校验的时候,这个csrf_exempt只能给dispatch方法装饰(在CBV中想要使用局部不校验,只能装饰在重写父类的dispatch函数上)。

原文地址:https://www.cnblogs.com/cnhyk/p/12274325.html

时间: 2024-10-08 10:48:22

第十篇:跨站请求伪造csrf的相关文章

跨站请求伪造CSRF原理

跨站请求伪造CSRF原理 CSRF是Cross Site Request Forgery的缩写,CSRF是伪造成合法用户发起请求 先了解下session: 用户登录时服务器端生成一个Session 返回给用户session_id在cookie中 用户下次登录带着有session_id的cookie登录 跨站请求伪造例子 只有session的话,如果有一个网站可以访问所有的cookie,那么就会获取到所有的session,然后带着你的session去访问别的网站. 比如:在一些诱骗性的网站上,可以

跨站请求伪造CSRF(Cross-site request forgery)

CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用 一般被攻击步骤: 1.登录受信任网站A,并在本地生成Cookie. 2.在不登出A的情况下,访问危险网站B. 所以没事的时候不要乱点链接不是随便说着玩的. 常见场景分析: 假设你有一个这样的Action,因为已经加了[Authorize(Roles = "Admins")]标记

跨站请求伪造 CSRF / XSRF&lt;一:介绍&gt;

跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法. ***跟跨网站脚本(XSS)相比,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任. 攻击的细节 跨站请求攻击,简单地说,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并执

跨站请求伪造(csrf)

跨站请求伪造(csrf) 钓鱼网站 ? 就类似于你搭建了一个跟银行一模一样的web页面 ? 用户在你的网站转账的时候输入用户名 密码 对方账户 ? 银行里面的钱确实少了 但是发现收款人变了 最简单的原理 你写的form表单中 用户的用户名 密码都会真实的提交给银行后台 但是收款人的账户却不是用户填的 你暴露给用户的是一个没有name属性的input框 你自己提前写好了一个隐藏的带有name和value的input框 真正的网站 前端 <h1>真正的网站</h1> <form

跨站请求伪造CSRF

CSRF是Cross Site Request Forgery的缩写,乍一看和XSS差不多的样子,但是其原理正好相反,XSS是利用合法用户获取其信息,而CSRF是伪造成合法用户发起请求. 在XSS危害--session劫持中我们提到了session原理,用户登录后会把登录信息存放在服务器,客户端有一个用户标识存在cookie中,只要用户不关闭浏览器或者退出登录,在其有效期内服务器就会把这个浏览器发送的请求当作当前客户,如果这时候用户被欺骗,使用浏览器打开了某些恶意网址,里面就会包含一些不是用户希

跨站请求伪造(CSRF攻击)理解

一  概念 你这可以这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求.CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账......造成的问题包括:个人隐私泄露以及财产安全. 二  过程 1  受害者 Bob 在银行有一笔存款,通过对银行的网站发送请求 http://bank.example/withdraw?account=bob&amount=1000000&for=bob2 可以使 Bob 把 1000000 的存款转到

跨站请求伪造 CSRF / XSRF&lt;二:应用&gt;

防御的方法主要有两种<java示例> 1.检查Referer字段 HTTP头中有一个Referer字段,这个字段用以标明请求来源于哪个地址.在处理敏感数据请求时,通常来说,Referer字段应和请求的地址位于同一域名下.以上文银行操作为例,Referer字段地址通常应该是转账按钮所在的网页地址,应该也位于www.examplebank.com之下.而如果是CSRF攻击传来的请求,Referer字段会是包含恶意网址的地址,不会位于www.examplebank.com之下,这时候服务器就能识别出

防止跨站请求伪造(CSRF)攻击 和 防重复提交 的方法的实现

CSRF的概率可以参考:http://netsecurity.51cto.com/art/200812/102951.htm 本文介绍的是基于spring拦截器的Spring MVC实现 首先配置拦截器: <mvc:interceptors> <mvc:interceptor> <!-- 匹配的是url路径, 如果不配置或/**,将拦截所有的Controller --> <mvc:mapping path="/xxx/**" /> <

Django框架进阶7 django请求生命周期流程图, django中间件, csrf跨站请求伪造, auth认证模块

django请求生命周期流程图 djang中间件 它是django的门户 只要是全局相关的功能你都应该考虑使用django中间件来帮你完成 全局用户身份校验 全局用户访问频率校验 用户访问黑名单 用户访问白名单 # 只要以后用django开发业务 设计到全局相关的功能 你就考虑用中间件 MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.Sessio