fix: XSS — _esc() для o.operation в instances.js (v1.2.40)

Результат код-ревью #1 (критическое):
  o.operation вставлялся в onclick и innerHTML без экранирования.
  Исправлено: JS-escape для onclick (\\, \'), HTML-escape для текста.
This commit is contained in:
2026-08-03 10:51:02 +04:00
parent 3293330cec
commit 06137d6082
2 changed files with 8 additions and 4 deletions
+1 -1
View File
@@ -32,7 +32,7 @@ from routes.api_scenario_defs import bp_defs as api_scenario_defs_bp
# Версия — показывается в топбаре UI. Меняется при КАЖДОМ изменении кода. # Версия — показывается в топбаре UI. Меняется при КАЖДОМ изменении кода.
# Нужна для фильтрации истории (пользователь видит только записи своей версии). # Нужна для фильтрации истории (пользователь видит только записи своей версии).
VERSION = "1.2.39" VERSION = "1.2.40"
# Flask-приложение с Jinja2-шаблонами из папки templates/ # Flask-приложение с Jinja2-шаблонами из папки templates/
app = Flask(__name__, template_folder="templates", static_folder="static") app = Flask(__name__, template_folder="templates", static_folder="static")
+7 -3
View File
@@ -143,9 +143,13 @@ async function toggleInstance(iuid){
} }
// Кнопки операций с цветовой маркировкой // Кнопки операций с цветовой маркировкой
opsEl.innerHTML=ops.map(o=> // o.operation в onclick — JS-escape: \ → \\, ' → \'
`<button class="btn btn-sm op-btn ${opClass(o.operation)}" onclick="runOp('${o.operation}',${o.svcOperationId})">${o.operation}</button>` // o.operation в тексте кнопки — HTML-escape через _esc()
).join(''); opsEl.innerHTML=ops.map(o=>{
const escOp = _esc(o.operation);
const jsOp = o.operation.replace(/\\/g,'\\\\').replace(/'/g,"\\'");
return `<button class="btn btn-sm op-btn ${opClass(o.operation)}" onclick="runOp('${jsOp}',${o.svcOperationId})">${escOp}</button>`;
}).join('');
opsEl.classList.add('open'); opsEl.classList.add('open');
}catch(e){ }catch(e){
opsEl.innerHTML='<span style="color:var(--destructive);font-size:11px;">Ошибка загрузки</span>'; opsEl.innerHTML='<span style="color:var(--destructive);font-size:11px;">Ошибка загрузки</span>';