国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

python Flask 裝飾器順序問題解決

2020-02-15 22:42:57
字體:
來源:轉載
供稿:網友

上周 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 裝飾器順序:

    如果 @app.route 在內層,那么就會把最原始的 view 函數傳給 add_url_rule , Flask 框架就會添加一條 URL 規則,指向最原始的 view 函數。 如果 @app.route 在外層,那么就會把已經被 login_required 裝飾過的 view 函數傳給 add_url_rule , Flask 框架就會添加一條 URL 規則,指向已經裝飾過的 view 函數。

下面是兩個例子,來說明:

正確寫法

@user_blueprint.route('/admin/refresh_session/', methods=['POST'])@login_requireddef refresh_session(): pass

這段代碼相當于:

# 這里沒有裝飾器def refresh_session(): passlogin_wrapped = login_required(refresh_session) # login 裝飾器both_wrapped = app.route('/admin/refresh_session/')(login_wrapped) # route 裝飾器

/admin/refresh_session/ 這條路由指向的實際是

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 运城市| 松江区| 宁晋县| 静安区| 营山县| 政和县| 钟祥市| 朔州市| 张家港市| 黄冈市| 青川县| 兰考县| 南江县| 崇信县| 武乡县| 西乌| 子长县| 贵定县| 长沙市| 通州区| 丹寨县| 岚皋县| 安平县| 罗山县| 鹤庆县| 静安区| 太康县| 苏尼特左旗| 永清县| 云龙县| 陆良县| 济南市| 台东县| 无极县| 崇文区| 平陆县| 五大连池市| 南郑县| 丁青县| 垦利县| 平原县|