上周 RealWorld CTF 2018 web 题 bookhub 有个未授权访问的漏洞,比较有意思,赛后看了一下公开的 WriteUp,大家也都没写清楚,所以就有了这篇博文。
前言
这个题是用 flask 框架写的,在 www/bookhub/views/user.py 中, refresh_session 方法存在未授权访问漏洞,代码是这样写的:
@login_required @user_blueprint.route('/admin/system/refresh_session/', methods=['POST']) def refresh_session(): pass # 这里省略内容
注意看 @login_required 这个装饰器写在了 route 装饰器上面了,导致了 login_required 未调用。那么,为什么会这样子呢?
官方文档
Flask 官方文档中关于Login Required Decorator说明 这一节里面有一行说明:
To use the decorator, apply it as innermost decorator to a view function. When applying further decorators, always remember that the route() decorator is the outermost.
大概意思就是,必须保证 route 装饰器在最顶层
那么为什么要这样提示呢?
Python 装饰器顺序说明
本节内容可直接参考: Python 装饰器执行顺序迷思
总结一下就是,装饰的顺序按靠近函数顺序执行,从内到外装饰,调用时由外而内,执行顺序和装饰顺序相反。
回过头来看 Flask
Flask 框架中, route 装饰器是这么写的:
def route(self, rule, **options): """Like :meth:`Flask.route` but for a blueprint. The endpoint for the :func:`url_for` function is prefixed with the name of the blueprint. """ def decorator(f): endpoint = options.pop("endpoint", f.__name__) self.add_url_rule(rule, endpoint, f, **options) return f return decorator
route 调用了 add_url_rule , 对传入的 f 添加一条 URL 规则。
所以,按照 python 装饰器顺序:
下面是两个例子,来说明:
正确写法
@user_blueprint.route('/admin/refresh_session/', methods=['POST']) @login_required def refresh_session(): pass
这段代码相当于:
# 这里没有装饰器 def refresh_session(): pass login_wrapped = login_required(refresh_session) # login 装饰器 both_wrapped = app.route('/admin/refresh_session/')(login_wrapped) # route 装饰器
/admin/refresh_session/ 这条路由指向的实际是 login_wrapped ,这样就会经过 login 检查
错误写法
@login_required @user_blueprint.route('/admin/refresh_session/', methods=['POST']) def refresh_session(): pass
这段代码相当于:
# 这里没有装饰器 def refresh_session(): pass route_wrapped = app.route('/admin/refresh_session/')(refresh_session) # route 装饰器 login_wrapped = login_required(route_wrapped) # login 装饰器
/admin/refresh_session/ 这条路由指向的实际是 refresh_session , 而 login_wrapped 并没有与路由挂勾,所以不会被调用
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:notice#nhooo.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。