防止跨站攻击——CSRFToken

防止跨站攻击——CSRFToken,第1张

CSRF:无法获取受害者的cookie,无法看到cookie;

只是利用受害者是被服务器信任的(靠验证cookie),而给服务器发送请求

怎么防止跨站攻击

表单:在 Form 表单中添加一个隐藏的的字段,值是 csrf_token。

非表单:在ajax获取数据时,添加headers:{ 'X-CSRFToken':getCookie('csrf_token') }。

原理:在浏览器访问网站A时,网站A设置cookie会增加随机值csrf_token,这个值是随机的。返回给浏览器时,cookie会储存在浏览器,同时会把csrf_token传给表单里面的隐藏字段。所以当浏览器用自己的表单时会自带csrf_token,网站A取到这个值和cookie里的csrf_token一致就通过。而网站B里面的表单没有这个值,所以不能通过,这样就阻止了恶意攻击。非表单也是这样的原理。

django中写form表单时csrf_token的作用: https://blog.csdn.net/up1012/article/details/81032368

Django下的CSRF预防机制

https://www.cnblogs.com/freely/p/6928822.html

CSRF预防机制

CSRF的防御可以从服务端和客户端两方面着手,防御效果是从服务端着手效果比较好,现在一般的CSRF防御也都在服务端进行。

token防御的整体思路是:

第一步:后端随机产生一个token,把这个token保存在SESSION状态中;同时,后端把这个token交给前端页面;

第二步:下次前端需要发起请求(比如发帖)的时候把这个token加入到请求数据或者头信息中,一起传给后端;

第三步:后端校验前端请求带过来的token和SESSION里的token是否一致;

1、Django下的CSRF预防机制

django 第一次响应来自某个客户端的请求时,会在服务器端随机生成一个 token,把这个 token 放在 cookie 里。然后每次 POST 请求都会带上这个 token,

这样就能避免被 CSRF 攻击。

在 templete 中, 为每个 POST form 增加一个 {% csrf_token %} tag. 如下:

在返回的 HTTP 响应的 cookie 里,django 会为你添加一个 csrftoken 字段,其值为一个自动生成的 token

在所有的 POST 表单模板中,加一个{% csrf_token %} 标签,它的功能其实是给form增加一个隐藏的input标签,如下

,而这个csrf_token = cookie.csrftoken,在渲染模板时context中有context['csrf_token'] = request.COOKIES['csrftoken']

在通过表单发送POST到服务器时,表单中包含了上面隐藏了crsrmiddlewaretoken这个input项,服务端收到后,django 会验证这个请求的 cookie 里的 csrftoken 字段的值和提交的表单里的 csrfmiddlewaretoken 字段的值是否一样。如果一样,则表明这是一个合法的请求,否则,这个请求可能是来自于别人的 csrf 攻击,返回 403 Forbidden.

在通过 ajax 发送POST请求到服务器时,要求增加一个x-csrftoken header,其值为 cookie 里的 csrftoken 的值,服务湍收到后,django会验证这个请求的cookie里的csrftoken字段与ajax post消息头中的x-csrftoken header是否相同,如果相同,则表明是一个合法的请求

具体实现方法

django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成。而对于django中设置防跨站请求伪造功能有分为全局和局部。

全局:

中间件 django.middleware.csrf.CsrfViewMiddleware

局部:

@csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。

@csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。

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

1、原理

在客户端页面上添加csrftoken, 服务器端进行验证,服务器端验证的工作通过'django.middleware.csrf.CsrfViewMiddleware'这个中间层来完成。在django当中防御csrf攻击的方式有两种:

1.在表单当中附加csrftoken

2.通过request请求中添加X-CSRFToken请求头。

注意:Django默认对所有的POST请求都进行csrftoken验证,若验证失败则403错误侍候。

Django 设置 cookie 中的 csrftoken

http://www.mamicode.com/info-detail-2062660.html

VUE向django发送post返回403:CSRF Failed: CSRF token missing or incorrect解决方案:

https://blog.csdn.net/LoHiauFung/article/details/80792334

http://www.cnblogs.com/wangwei916797941/p/9283776.html

django post出现403的解决办法 据说,从django1.x开始,加入了CSRF保护。

CSRF(Cross-site request forgery跨站请求伪造,也被称成为“one click attack”或者session riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,并且攻击方式几乎相左。XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。-------来自百度百科

报错:Forbidden (403)

CSRF verification failed. Request aborted.Help

Reason given for failure:CSRF token missing or incorrect.

In general, this can occur when there is a genuine Cross Site Request Forgery, or when Django's CSRF mechanism has not been used correctly. For POST forms, you need to ensure:

Your browser is accepting cookies.

The view function uses RequestContext for the template, instead of Context.

In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.

If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data.

You're seeing the help section of this page because you have DEBUG = True in your Django settings file. Change that to False, and only the initial error message will be displayed.

You can customize this page using the CSRF_FAILURE_VIEW setting.

在网上找解决办法,说是提交参数中要有csrf_token,才能成功。但网上都是1.3或者1.4版本的解决办法,在1.5版本中测试已经不能用了。

在1.5.1版本,我测试可行的解决办法有三种:

一:

关闭csrf保护功能。为视图函数添加@csrf_exempt修饰符。

from django.views.decorators.csrf import csrf_exempt@csrf_exemptdef view(request): #your code..... 当然这样不安全。

二: 在模版文件中,每个form提交域中都加上{% csrf_token %}标签,并使用render函数返回视图,或者强行使用RequestContext 代替Context。例: from django.shortcuts import renderdef contact(request): form = ContactForm()#这里我使用了一个django的表格 return render(request,'contact.html', {'form': form})

或者:

from django.shortcuts import render_to_responsedef contact(request): form = ContactForm()#这里我使用了一个django的表格 return render_to_response('contact.html', {'form': form}, context_instance=RequestContext(request) )

contact.html的内容:

<html><head><style type="text/css">ul.errorlist { margin: 0padding: 0} .errorlist li { background-color: redcolor: whitedisplay: blockfont-size: 10pxmargin: 0 0 3pxpadding: 4px 5px}</style><title>send</title></head><body><h1>Contact us</h1><form action="" method="post">{% csrf_token %} <div class="field">{{ form.subject.errors }} <label for="id_subject">工作:</label>{{ form.subject }} </div><div class="field">{{ form.email.errors }} <label for="id_email">你的邮箱地址:</label>{{ form.email }} </div><div class="field">{{ form.message.errors }} <label for="id_message">消息:</label>{{ form.message }} </div><input type="submit" value="Submit"></form></body></html>

三:

方法二显然只能限制在django模版中使用,那如果我们使用javascript或者AJAX的时候呢?怎么添加csrf_token呢?

我们可以使用javascript来提取cookies中的csrf_token。

function getCookie(name) { var cookieValue = nullif (document.cookie &&document.cookie != '') { var cookies = document.cookie.split('')for (var i = 0i <cookies.lengthi++) { var cookie = jQuery.trim(cookies[i])if (cookie.substring(0, name.length + 1) == (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1))break} } } return cookieValue}

或者这个好理解的:

function getCookie(sName){ var aCookie=document.cookie.split("")for(var i=0i<aCookie.lengthi++){ var aCrumb=aCookie[i].split("=")if(sName==aCrumb[0])return (aCrumb[1])} return null}

AJAX中这样用: $.post(url, {"csrfmiddlewaretoken":getCookie('csrftoken')}, function (data) {alert(data)})

但是有一个问题,当有一个新用户访问这个页面的时候,cookie里并没有csrftoken这个值。只有进行第二种方法,才能在cookie里生成csrftoken值。解决此问题的方法随后更新。

完全可以满足简单的建站需要。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/bake/11823534.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-19
下一篇 2023-05-19

发表评论

登录后才能评论

评论列表(0条)

保存