fix: whitelist mode/polygon_stand — защита от мусора в cookie (v1.2.42)
Результат код-ревью #3: mode/polygon_stand принимали любые значения из формы. Добавлена валидация в main.py (set_mode) и auth.py (get_mode, get_polygon_stand): mode ∈ {polygon, cloud}, stand ∈ {dev, test, prod}.
This commit is contained in:
+8
-2
@@ -55,14 +55,20 @@ def get_mode():
|
|||||||
Иначе — из cookie, по умолчанию эмуляция."""
|
Иначе — из cookie, по умолчанию эмуляция."""
|
||||||
if not current_app.config.get("POLYGON_ENDPOINT", ""):
|
if not current_app.config.get("POLYGON_ENDPOINT", ""):
|
||||||
return "cloud"
|
return "cloud"
|
||||||
return request.cookies.get("mode", "polygon")
|
mode = request.cookies.get("mode", "polygon")
|
||||||
|
if mode not in ("polygon", "cloud"):
|
||||||
|
mode = "polygon"
|
||||||
|
return mode
|
||||||
|
|
||||||
|
|
||||||
def get_polygon_stand():
|
def get_polygon_stand():
|
||||||
"""Стенд полигона: 'test' (по умолчанию), 'dev', 'prod'.
|
"""Стенд полигона: 'test' (по умолчанию), 'dev', 'prod'.
|
||||||
|
|
||||||
Используется ТОЛЬКО в режиме эмуляции — для построения URL и load_service_ids."""
|
Используется ТОЛЬКО в режиме эмуляции — для построения URL и load_service_ids."""
|
||||||
return request.cookies.get("polygon_stand", "test")
|
stand = request.cookies.get("polygon_stand", "test")
|
||||||
|
if stand not in ("dev", "test", "prod"):
|
||||||
|
stand = "test"
|
||||||
|
return stand
|
||||||
|
|
||||||
|
|
||||||
def get_token():
|
def get_token():
|
||||||
|
|||||||
+1
-1
@@ -32,7 +32,7 @@ from routes.api_scenario_defs import bp_defs as api_scenario_defs_bp
|
|||||||
|
|
||||||
# Версия — показывается в топбаре UI. Меняется при КАЖДОМ изменении кода.
|
# Версия — показывается в топбаре UI. Меняется при КАЖДОМ изменении кода.
|
||||||
# Нужна для фильтрации истории (пользователь видит только записи своей версии).
|
# Нужна для фильтрации истории (пользователь видит только записи своей версии).
|
||||||
VERSION = "1.2.41"
|
VERSION = "1.2.42"
|
||||||
|
|
||||||
# Flask-приложение с Jinja2-шаблонами из папки templates/
|
# Flask-приложение с Jinja2-шаблонами из папки templates/
|
||||||
app = Flask(__name__, template_folder="templates", static_folder="static")
|
app = Flask(__name__, template_folder="templates", static_folder="static")
|
||||||
|
|||||||
@@ -107,9 +107,13 @@ def index():
|
|||||||
# Обработка action=set_mode: сохранить режим и стенд в cookie
|
# Обработка action=set_mode: сохранить режим и стенд в cookie
|
||||||
if action == "set_mode":
|
if action == "set_mode":
|
||||||
new_mode = request.form.get("mode", "polygon")
|
new_mode = request.form.get("mode", "polygon")
|
||||||
|
if new_mode not in ("polygon", "cloud"):
|
||||||
|
new_mode = "polygon"
|
||||||
# polygon_stand: из формы, иначе — сохранить предыдущее значение из cookie
|
# polygon_stand: из формы, иначе — сохранить предыдущее значение из cookie
|
||||||
# (нужно при переключении Облако→Эмуляция — радио стенда нет в DOM)
|
# (нужно при переключении Облако→Эмуляция — радио стенда нет в DOM)
|
||||||
new_stand = request.form.get("polygon_stand") or request.cookies.get("polygon_stand", "test")
|
new_stand = request.form.get("polygon_stand") or request.cookies.get("polygon_stand", "test")
|
||||||
|
if new_stand not in ("dev", "test", "prod"):
|
||||||
|
new_stand = "test"
|
||||||
resp = make_response(redirect("/"))
|
resp = make_response(redirect("/"))
|
||||||
resp.set_cookie("mode", new_mode, max_age=60*60*24*365, httponly=True, samesite="Strict", secure=True)
|
resp.set_cookie("mode", new_mode, max_age=60*60*24*365, httponly=True, samesite="Strict", secure=True)
|
||||||
resp.set_cookie("polygon_stand", new_stand, max_age=60*60*24*365, httponly=True, samesite="Strict", secure=True)
|
resp.set_cookie("polygon_stand", new_stand, max_age=60*60*24*365, httponly=True, samesite="Strict", secure=True)
|
||||||
|
|||||||
Reference in New Issue
Block a user