From 06137d60827a0cc6e7066ebe4d40c688c35ef1e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Mon, 3 Aug 2026 10:51:02 +0400 Subject: [PATCH] =?UTF-8?q?fix:=20XSS=20=E2=80=94=20=5Fesc()=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20o.operation=20=D0=B2=20instances.js=20(v1.2.40)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Результат код-ревью #1 (критическое): o.operation вставлялся в onclick и innerHTML без экранирования. Исправлено: JS-escape для onclick (\\, \'), HTML-escape для текста. --- site/app.py | 2 +- site/static/js/instances.js | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/site/app.py b/site/app.py index 2cdc414..d16a64c 100644 --- a/site/app.py +++ b/site/app.py @@ -32,7 +32,7 @@ from routes.api_scenario_defs import bp_defs as api_scenario_defs_bp # Версия — показывается в топбаре UI. Меняется при КАЖДОМ изменении кода. # Нужна для фильтрации истории (пользователь видит только записи своей версии). -VERSION = "1.2.39" +VERSION = "1.2.40" # Flask-приложение с Jinja2-шаблонами из папки templates/ app = Flask(__name__, template_folder="templates", static_folder="static") diff --git a/site/static/js/instances.js b/site/static/js/instances.js index e6d3d38..a68df96 100644 --- a/site/static/js/instances.js +++ b/site/static/js/instances.js @@ -143,9 +143,13 @@ async function toggleInstance(iuid){ } // Кнопки операций с цветовой маркировкой - opsEl.innerHTML=ops.map(o=> - `` - ).join(''); + // o.operation в onclick — JS-escape: \ → \\, ' → \' + // o.operation в тексте кнопки — HTML-escape через _esc() + opsEl.innerHTML=ops.map(o=>{ + const escOp = _esc(o.operation); + const jsOp = o.operation.replace(/\\/g,'\\\\').replace(/'/g,"\\'"); + return ``; + }).join(''); opsEl.classList.add('open'); }catch(e){ opsEl.innerHTML='Ошибка загрузки';