war-stories2026-11-105 menit
War Story: Race Condition Anti-Cheat Proctoring & Heartbeat Watchdog di Node.js
Bagaimana tab browser yang dijeda debugger dan event blur/fullscreen memicu duplikasi strike sebelum kita mengunci aturan evaluasi di sisi server.
#Backend#Linux
Jebakan Validasi Client-Side
Pada sistem proctoring psikotest (localhost:3000), klien mengirim laporan pelanggaran seperti TAB_SWITCH, WINDOW_BLUR, DEVTOOLS_OPEN, dan EXIT_FULLSCREEN. Awalnya, satu kali Alt+Tab bisa memicu WINDOW_BLUR dan TAB_SWITCH dalam rentang 12 milidetik yang sama, sehingga peserta langsung terkena penalti ganda.
Deduplikasi & Authoritative Strike Engine
Aturan bobot risiko (risk dan strike) dipindahkan seluruhnya menjadi tabel otoritatif di server Node.js, lengkap dengan cooldown window per jenis pelanggaran agar transisi jendela sistem tidak menggandakan penalti.
const VIOLATION_RULES = {
TAB_SWITCH: { severity: 'HIGH', risk: 25, strike: 1 },
WINDOW_BLUR: { severity: 'HIGH', risk: 20, strike: 1 },
DEVTOOLS_OPEN: { severity: 'CRITICAL', risk: 50, strike: 2 },
HEARTBEAT_TIMEOUT: { severity: 'HIGH', risk: 25, strike: 1 }
};
function shouldAcceptViolation(session, type, nowMs) {
const last = session.lastViolationAt?.[type] ?? 0;
if (nowMs - last < 2500) return false;
session.lastViolationAt[type] = nowMs;
return true;
}Pelajaran Utama
- Jangan pernah memercayai nilai skor atau strike yang dikirim oleh payload browser.
- Pasang heartbeat watchdog di server agar peserta yang menghentikan eksekusi JS lewat breakpoint debugger tetap terdeteksi sebagai
HEARTBEAT_TIMEOUT.