v0.0.73: фиксы по код-ревью Соннета — SSRF, path traversal, слабый SID, proc_error, zip-бомба, self-XSS
Deploy drhider / validate (push) Canceled after 0s

This commit is contained in:
“Naeel”
2026-08-24 19:58:27 +03:00
parent 4b73657e4c
commit ff4895b63b
7 changed files with 85 additions and 10 deletions
+11 -2
View File
@@ -280,6 +280,7 @@ function fmtSec(s) {
// Эмпирическая оценка времени обработки файла: сек/МБ (ориентировочно, до старта)
const EST_MB_SEC = 12;
function estForFile(f) { return f ? Math.max(1, Math.round(f.size / 1048576 * EST_MB_SEC)) : 0; }
function esc(s) { return String(s).replace(/[&<>"']/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c])); }
function rr() {
if (procPhase === 'processing') { renderProcTable(); return; }
@@ -290,7 +291,7 @@ function rr() {
const rowCls = over ? ' class="row-over"' : '';
const stTxt = over ? '<span style="color:#c0392b;">🔥 не учитывается</span>'
: '<span style="color:#7d3c98;">~' + fmtSec(estForFile(f)) + '</span>';
return '<tr id="row-' + i + '"' + rowCls + '><td class="name-cell">' + f.name + '</td><td class="num-cell">' + fs(f.size) + '</td><td class="num-cell" id="st-' + i + '" style="font-size:12px;">' + stTxt + '</td><td><button class="remove-btn" onclick="rm(' + i + ')">✕</button></td></tr>';
return '<tr id="row-' + i + '"' + rowCls + '><td class="name-cell">' + esc(f.name) + '</td><td class="num-cell">' + fs(f.size) + '</td><td class="num-cell" id="st-' + i + '" style="font-size:12px;">' + stTxt + '</td><td><button class="remove-btn" onclick="rm(' + i + ')">✕</button></td></tr>';
}).join('');
}
const overCount = sf.filter(f => overNames.has(f.name)).length;
@@ -307,7 +308,7 @@ function procRow(i, stTxt) {
const over = overNames.has(f.name);
const cls = (procState[i] && procState[i].st === 'current') ? ' class="row-current"'
: (over ? ' class="row-over"' : '');
return '<tr' + cls + '><td class="name-cell">' + f.name + '</td><td class="num-cell">' + fs(f.size) + '</td><td class="num-cell" style="font-size:12px;">' + stTxt + '</td><td></td></tr>';
return '<tr' + cls + '><td class="name-cell">' + esc(f.name) + '</td><td class="num-cell">' + fs(f.size) + '</td><td class="num-cell" style="font-size:12px;">' + stTxt + '</td><td></td></tr>';
}
function renderProcTable() {
@@ -936,6 +937,14 @@ async function uploadFiles() {
document.getElementById('newSessionBtn').style.display = 'inline-block';
resolve();
});
activeES.addEventListener('proc_error', function(e) {
const d = JSON.parse(e.data);
finishProcUI();
setBusy(false);
st.className = 'status error';
st.textContent = 'Ошибка обработки: ' + (d.error || 'неизвестная ошибка');
resolve();
});
activeES.onerror = function() {
finishProcUI();
reject(new Error('SSE connection failed'));