qq空间留言仅彼此可见设为彼此可见以后 这条留言的人知不知道我把它设置成了仅彼此可见

浅谈cnode社区如何防止csrf攻击 - CNode技术社区
秦晋之巅社区(qjzd.net)作者
csrf是什么
csrf(Cross-site request forgery)跨站请求伪造, 具体谷歌度娘.
防止csrf攻击简单思路:
在服务器上生成一个token, web端发起的请求都带上token这个参数, 请求中的token与服务端的token不一致,则抛出错误.
涉及主要模块代码
layout.html, jquery-ujs.js, app.js, csurf模块
1 服务端如何生产成token, token存储的位置
app.use(function (req, res, next) {
if (req.path.indexOf('/api') === -1) {
csurf()(req, res, next);
因csurlf未带入参{ cookie: true }, 故token将会保存session中(其实session不是存放token, 而是能一个secret, 通过secret可生产token且能还原token)
csurf()(req, res, next); 该行代码被执行时, 会在为req添加一个方法csrfToken, 接下来来会用到, 如下所示.
app.use(function (req, res, next) {
res.locals.csrf = req.csrfToken ? req.csrfToken() : '';
req.csrfToken() ; 该行代码被执行,会生成一个token, 并保存session中.
req.csrfToken()保存token的部分代码, 如下所示.
csurf模块 index.js
// generate & set new secret
if (sec === undefined) {
sec = tokens.secretSync()
setsecret(req, res, sec, cookie)
2 服务端什么时候校验
app.use(function (req, res, next) {
if (req.path.indexOf('/api') === -1) {
csurf()(req, res, next);
除/api开头请求, 都会执行csurf方法, token的校验也是在该方法里, csurf方法部分代码如下所示
csurf模块 index.js
verifytoken(req, tokens, secret, value(req))
3 服务端校验的token, 可能来自哪里.
web端请求中的token, 不一定只来自于所传送的参数.
csurf模块 index.js
function defaultValue(req) {
return (req.body && req.body._csrf)
|| (req.query && req.query._csrf)
|| (req.headers['x-csrf-token'])
|| (req.headers['x-xsrf-token']);
因csurlf初始化时没带任何参数,
故校验的token使用使用默认的值,
从代码上, 默认的token可能来自req.body, req.query, req.header
4 哪些请求不校验token.
从app.js 的代码中可以看出, /api开头的请求是不会校验的, 但果真如此么, 如果真是这样, 那不是访问首页, 都会被拦截.
csurf模块 index.js
// verify the incoming token
if (!ignoreMethod[req.method]) {
verifytoken(req, tokens, secret, value(req))
从代码上, 部分req.method方法是被忽略校验的, 那到底是什么mehtod呢, 具体如下所示
csurf模块 index.js
// ignored methods
var ignoreMethods = options.ignoreMethods === undefined
? ['GET', 'HEAD', 'OPTIONS']
: options.ignoreMethods
因csurlf初始化时没带任何参数, 故使用默认的ignoreMethods, get head option会被忽略校验, 所以我们就可以很正常的访问首页
5 token什么时候到页面上的.
app.use(function (req, res, next) {
res.locals.csrf = req.csrfToken ? req.csrfToken() : '';
layout.xml
&meta content=&_csrf& name=&csrf-param&&
&meta content=&&%= csrf %&& name=&csrf-token&&
在页面初始化的时候, token被放在到了 meta标签后, 之后请求数据, 就可以利用这些值了.
6 web端token参数什么时候传到服务端.
web端的token需要时请求时传入的, 但是现在只有meta标签有csrf-token的值, 这个token时什么时候被利用的呢
jquery.ujs.js
// Make sure that every Ajax request sends the CSRF token
CSRFProtection: function (xhr) {
var token = $('meta[name=&csrf-token&]').attr('content');
if (token) xhr.setRequestHeader('X-CSRF-Token', token);
// making sure that all forms have actual up-to-date token(cached forms contain old one)
refreshCSRFTokens: function () {
var csrfToken = $('meta[name=csrf-token]').attr('content');
var csrfParam = $('meta[name=csrf-param]').attr('content');
$('form input[name=&' + csrfParam + '&]').val(csrfToken);
jquery.ujs.js
$.ajaxPrefilter(function (options, originalOptions, xhr) {
if (!options.crossDomain) {
rails.CSRFProtection(xhr);
jquery.ujs.js
$(function () {
rails.refreshCSRFTokens();
从代码中看出, 在发ajax请求的时候,会在header.X-CSRF-Token附上token值.
在form表单请求的时候, 会添加token的值.
以上代码摘录于cnnode源码git版本号为a52a6deb50667fff
以上如有理解不当之处, 望提点指正.
哎哟,被加精了,感谢感谢~.~
这样的防御csrf机制,只是防御一些url劫持或xss之后的csrf,加了token
就算你判断referrer
也不可能防刷。
如果写一个自动化的脚本,自动化地执行以下逻辑: 先向种token的url发起一个get请求取得token,再向需要刷的/api接口发送post/get请求,这层防御机制就被破了。
加referrer也是对于来自浏览器的http请求进行了限制,
但是黑客写自动化脚本伪造的请求,你根本不可能用token+referrer的形式防住。
要防,还是得上万恶的验证码。
csrf是防止跨站请求伪造。
比如你在一台机器同时打开了两个标签页a网站和b网站, 如果用户a网站已经登入,并打开b网站点击了某个按钮,刚好这个按钮背后伪造并发起a网站的请求,比如购买商品的请求,因为cookie对同一个url是共享的,会导致用户被恶意购买商品。
csrf是解决此类问题,并不是为了解决防刷问题。要解决防刷应该在服务端对ip等信息做访问限制,万恶的验证码也可以,不过验证码用户体验真的太差了,登入的时候用用也就可以了。
还设置了不允许外部网站使用iframe引入cnode
X-Frame-Options:SAMEORIGIN
rails的默认做法, 贴出了node的实现, 当赞!
对于什么是csrf,道哥的《白帽子web安全》清楚地说了,“如果一个请求中所有参数都是可以预期的,那么这个请求就有被csrf的风险”,我在博客中也对csrf的各种应用场景和实践经历进行了描述:
如果一定要抱着“跨站请求伪造”这个带有历史原因的漏洞名字不放, 那么XSS的名字还叫跨站脚本攻击呢,你能说你在一个留言板里直接输入个alert(1)那不算xss吗?
CNode 社区为国内最专业的 Node.js 开源技术社区,致力于 Node.js 的技术研究。
服务器赞助商为
,存储赞助商为
,由提供应用性能服务。
新手搭建 Node.js 服务器,推荐使用无需备案的Django使用csrf时cookie没有csrf_token的问题 - 简书
Django使用csrf时cookie没有csrf_token的问题
今天被这个问题困扰了一上午,理清以后发觉正常情况下是不会遇到这个问题的。遇到这个问题的前提是什么呢?
习惯ajax方式提交POST请求
习惯从cookie里找csrftoken
这次是在一个新建的project里遇到的这个问题,旧project的base foundation都比较完善,所以才没有特别注意csrftoken的来源问题。
一般我们认为cookie里的csrftoken是由csrftoken middleware所设置的,事实确实如此,但也不完全是。贴一段CsrfViewMiddleware的代码:
def process_response(self, request, response):
if getattr(response, 'csrf_processing_done', False):
return response
# If CSRF_COOKIE is unset, then CsrfViewMiddleware.process_view was
# never called, probably because a request middleware returned a response
# (for example, contrib.auth redirecting to a login page).
if request.META.get("CSRF_COOKIE") is None:
return response
# 重点在这里
if not request.META.get("CSRF_COOKIE_USED", False):
return response
# Set the CSRF cookie even if it's already set, so we renew
# the expiry timer.
response.set_cookie(settings.CSRF_COOKIE_NAME,
request.META["CSRF_COOKIE"],
max_age=settings.CSRF_COOKIE_AGE,
domain=settings.CSRF_COOKIE_DOMAIN,
path=settings.CSRF_COOKIE_PATH,
secure=settings.CSRF_COOKIE_SECURE,
httponly=settings.CSRF_COOKIE_HTTPONLY
# Content varies with the CSRF cookie, so set the Vary header.
patch_vary_headers(response, ('Cookie',))
response.csrf_processing_done = True
return response
这段代码的重点在于对CSRF_COOKIE_USED的检查,如果没有设置,middleware会直接返回response而不在cookie里设置csrftoken。而CSRF_COOKIE_USED是在哪设置的呢?有几种途径:
手动设置。在你的view里添加request.META["CSRF_COOKIE_USED"] = True
手动调用csrf middleware的get_token(request)或rotate_token(request)方法
在你的html模板里添加 {% csrf_token %}
我今天的问题就在于第三种途径。旧project里是有添加的,而新project里没有,所以导致了我的问题。
建议在每一个form里都添加这样的标签,这样能够在提交表单时自动将csrftoken添加进请求里。对于ajax post文档也指出从cookie拿会比较方便。
那这个标签具体做了什么呢?使用这个标签会让django模板引擎在这里插入一个隐藏的input用来存放csrftoken。在django.template.defaulttags里我们可以找到一个叫CsrfTokenNode的类,它的render方法检查了context里的csrf_token。
def render(self, context):
csrf_token = context.get('csrf_token', None)
if csrf_token:
if csrf_token == 'NOTPROVIDED':
return format_html("")
return format_html("&input type='hidden' name='csrfmiddlewaretoken' value='{}' /&", csrf_token)
context中的csrf_token是一个django.template.context_processors.csrf的实例,他本身就等同于自己的_get_val(),只不过是在每次用到自己的时候才调用该方法获得返回值。(这部分也是值得一写的内容)
所以可以看到在上面的render方法中的第二行,有一次对csrf_token的判断,正是在这里调用了_get_val,在_get_val中调用了get_token,get_token会从request里取CSRF_COOKIE,CSRF_COOKIE又是由middleware在process_view中提供的,所以最终会让CsrfViewMiddleware在process_response里把csrftoken添加进cookie里,也就可以在前端拿到cookie了。
总结一下,这之间发生的事情就是:
html文件添加{% csrf_token %}标签
CsrfViewMiddleware在process_view时向request添加CSRF_COOKIE
渲染模板检测到该标签,在渲染时添加CsrfTokenNode类
CsrfTokenNode的渲染方法检查csrf_token
对csrf_token进行判断时调用get_token
get_token检查request中的CSRF_COOKIE,并设置CSRF_COOKIE_USED为True
CsrfViewMiddleware在process_response设置cookie中的csrftoken
这样前端就能看到cookie了。
以上就是对这个问题的解决办法的记录。
原本是个写C++的匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。XSS及CSRF的详细介绍- Python教程-PHP中文网QQ群微信公众号XSS及CSRF的详细介绍一、XSS跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。1. 工作流程a. 恶意用户,在一些公共区域(例如,建议提交表单或消息公共板的输入表单)输入一些文本,这些文本被其它用户看到,但这些文本不仅仅是他们要输入的文本,同时还包括一些可以在客户端执行的脚本。如:&script&'Not Safe'&/script&b. 恶意提交这个表单c. 其他用户看到这个包括恶意脚本的页面并执行,获取用户的cookie等敏感信息。
2. 实例-未防范XSS攻击 1 pinglu = []
# 评论列表 2
3 #提交表单 4 def commit(request): 5
if request.method == 'GET': 6
return render(request, 'commit.html') 7
com = request.POST.get('commit') 9
pinglu.append(com)10
return redirect('/index.html/')11 12 13 #查看评论页面14 def index(request):15
return render(request, 'index.html', {'commit': pinglu})view.py 1 &!DOCTYPE html& 2 &html lang=&en&& 3 &head& 4
&meta charset=&UTF-8&& 5
&title&Title&/title& 6 &/head& 7 &body& 8 &h1&评论&/h1& 9 &form action=&/commit.html/& method=&post&&10
&input type=&text& name=&commit&&11
&input type=&submit& value=&sumbit&& {{ error }}12 &/form&13 &/body&14 &/html&commit.html 1 &!DOCTYPE html& 2 &html lang=&en&& 3 &head& 4
&meta charset=&UTF-8&& 5
&title&Title&/title& 6 &/head& 7 &body& 8 &h1&评论&/h1& 9 {% for item in commit %}10
&p&{{ item|safe }}&/p&11 {#
item后加safe,默认数据安全,django不会做特殊处理#}12 {% endfor %}13 &/body&14 &/html&index.html以上实例中,若在commit.html页面输入以下内容并提交:&script& alert('恶意脚本') &/script&则会在index页面执行此行代码,弹出警告框(若包含恶意代码,则会执行)3. 防范XSS攻击最直接的方法就是对于无法控制的输入在html页面内不要使用safe{#
&p&{{ item|safe }}&/p&#}&p&{{ item }}&/p&也可以在views里进行过滤,防止特殊字符提交到数据库或网页内def commit(request):if request.method == 'GET':return render(request, 'commit.html')else:
com = request.POST.get('commit')if '&script&' in com:
# 过滤“&script&”关键字,防止恶意代码的提交return render(request, 'commit.html', {'error': '此条评论有毒,已被和谐'})else:
pinglu.append(com)return redirect('/index.html/') 二、CSRFCSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。1. 工作流程攻击通过在授权用户访问的页面中包含链接或者脚本的方式工作:
2. django中如何防范django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成。而对于django中设置防跨站请求伪造功能有分为全局和局部。全局:启用中间件 django.middleware.csrf.CsrfViewMiddleware 局部:from django.views.decorators.csrf import csrf_exempt,csrf_protect@csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件@csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。 3. django中的具体应用方法form表单中添加{% csrf_token %}若form表单中未添加{% csrf_token %},则会报403错误。#settings.py中打开MIDDLEWARE设置'django.middleware.csrf.CsrfViewMiddleware',1 from django.shortcuts import render, HttpResponse, redirect2 3 def csrf_test(request):4
if request.method == 'GET':5
return render(request, 'csrf_test.html')6
return HttpResponse('ok')views.py 1 &!DOCTYPE html& 2 &html lang=&en&& 3 &head& 4
&meta charset=&UTF-8&& 5
&title&csef_test&/title& 6 &/head& 7 &body& 8 &form action=&/csrf_test.html/& method=&post&& 9
&input type=&text& name=&user& id=&user&&10
&input type=&submit& value=&submit&&11 &/form&12 13 &/body&14 &/html&csef_test.html修改csef_test.html: 1 &!DOCTYPE html& 2 &html lang=&en&& 3 &head& 4
&meta charset=&UTF-8&& 5
&title&csef_test&/title& 6 &/head& 7 &body& 8 &form action=&/csrf_test.html/& method=&post&& 9
{% csrf_token %}10
&input type=&text& name=&user& id=&user&&11
&input type=&submit& value=&submit&&12 &/form&13 14 &/body&15 &/html&form表单中添加{% csrf_token %}全站禁用,即将settings.py中的 'django.middleware.csrf.CsrfViewMiddleware' 注释掉即可基于FBV视图的局部禁用和使用 1 #settings.py 2 #启用 'django.middleware.csrf.CsrfViewMiddleware', 3
5 from django.views.decorators.csrf import csrf_exempt 6
8 @csrf_exempt 9 def csrf_test(request):10
if request.method == 'GET':11
return render(request, 'csrf_test.html')12
return HttpResponse('ok')局部禁用 1 #settings.py 2 #禁用 #'django.middleware.csrf.CsrfViewMiddleware', 3
5 from django.views.decorators.csrf import csrf_protect 6
8 @csrf_protect 9 def csrf_test(request):10
if request.method == 'GET':11
return render(request, 'csrf_test.html')12
return HttpResponse('ok')局部使用 基于CBV视图的(只能局部使用或禁用类,不能在类方法里局部使用或禁用 1 #settings.py 2 #禁用
'django.middleware.csrf.CsrfViewMiddleware', 3
5 from django.views import View 6 from django.views.decorators.csrf import csrf_protect 7 from django.utils.decorators import method_decorator 8
9 10 @method_decorator(csrf_protect, name='dispatch')11 class Foo(View):12
def get(self, request):13
def post(self, request):16
pass局部使用 1 #settings.py 2 #启用
'django.middleware.csrf.CsrfViewMiddleware', 3
5 from django.views import View 6 from django.views.decorators.csrf import csrf_exempt 7 from django.utils.decorators import method_decorator 8
9 10 @method_decorator(csrf_exempt, name='dispatch')11 class Foo(View):12
def get(self, request):13
def post(self, request):16
pass局部禁用Ajax提交数据时,携带CSRF 1 &!DOCTYPE html& 2 &html lang=&en&& 3 &head& 4
&meta charset=&UTF-8&& 5
&title&csef_test&/title& 6 &/head& 7 &body& 8 &form action=&/csrf_test.html/& method=&post&& 9
{% csrf_token %}10
&input type=&text& name=&user& id=&user&&11 {#
&input type=&submit& value=&submit&&#}12
&a onclick=&submitForm();&&Ajax提交表单&/a&13 &/form&14 15 &script src=&/static/jquery-3.2.1.js&&&/script&16 &script&17
function submitForm() {18
var csrf = $(&input[name='csrfmiddlewaretoken']&).val()19
var user = $(&#user&).val()20
$.ajax({21
url: '/csrf_test.html/',22
type: 'POST',23
data: {&user&: user, &csrfmiddlewaretoken&: csrf},24
success: function (arg) {25
console.log(arg);26
}29 &/script&30 &/body&31 &/html&Ajax重写csrf_test,html,csrf数据存放于data中 1 &!DOCTYPE html& 2 &html lang=&en&& 3 &head& 4
&meta charset=&UTF-8&& 5
&title&csef_test&/title& 6 &/head& 7 &body& 8 &form action=&/csrf_test.html/& method=&post&& 9
{% csrf_token %}10
&input type=&text& name=&user& id=&user&&11 {#
&input type=&submit& value=&submit&&#}12
&a onclick=&submitForm();&&Ajax提交表单&/a&13 &/form&14 15 &script src=&/static/jquery-3.2.1.js&&&/script&16 {#专门处理cookie的插件,提取cookie字符串#}17 &script src=&/static/jquery.cookie.js&&&/script&18 19 {#csrf数据放于data中#}20 {#&script&#}21 {#
function submitForm() {#}22 {#
var csrf = $(&input[name='csrfmiddlewaretoken']&).val();#}23 {#
var user = $(&#user&).val();#}24 {#
$.ajax({#}25 {#
url: '/csrf_test.html/',#}26 {#
type: 'POST',#}27 {#
data: {&user&: user, &csrfmiddlewaretoken&: csrf},#}28 {#
success: function (arg) {#}29 {#
console.log(arg);#}30 {#
}#}33 {#&/script&#}34 35 {#csrf数据放于请求头中#}36 &script&37
function submitForm() {38
var csrf = $.cookie('csrftoken');39
var user = $(&#user&).val();40
$.ajax({41
url: '/csrf_test.html/',42
type: 'POST',43
headers: {'X-CSRFToken': csrf},44
data: {&user&: user},45
success: function (arg) {46
console.log(arg);47
}50 &/script&51 52 53 54 &/body&55 &/html&Ajax重写csrf_test.html,csrf数据存放于headers中注意:{% csrf_token %}和cookie中的csrftoken值不一样。form表单中的隐藏csrf_token cookie中 以上就是XSS及CSRF的详细介绍的详细内容,更多请关注php中文网其它相关文章!770点赞收藏分享:&猜你喜欢12345678910
PHP中文网:独家原创,永久免费的在线,php技术学习阵地!Copyright
All Rights Reserved | 皖B2-QQ群:关注微信公众号}

我要回帖

更多关于 qq空间留言彼此可见 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信