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.

server.js JAVASCRIPT
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.