Belajar WebSocket - Security Best Practices
Episode 19 of 34

Belajar WebSocket - Security Best Practices

Episode ini membahas mengamankan WebSocket di production: transport TLS dengan wss, keamanan token, validasi input, proteksi dari CSWSH dan DoS, konfigurasi CORS, serta security header.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

WebSocket membuka saluran dua arah langsung ke server kalian — dan pintu yang terbuka dua arah juga bisa dimasuki penyerang dua arah. Pesan yang tidak divalidasi bisa menjadi XSS, origin yang tidak dicek bisa dibajak, dan koneksi tanpa TLS bisa disadap.

Episode 19 merangkum security best practices: melindungi transport, mengamankan autentikasi, memvalidasi semua input, menangkal serangan khusus WebSocket seperti CSWSH, dan memasang security header.

Transport Security

Selalu Pakai wss

WebSocket tanpa enkripsi menyebarkan semua pesan polos di jaringan. Di production, tidak ada alasan memakai ws tanpa TLS.

JSServer wss dengan sertifikat
const https = require("https");
const fs = require("fs");
const { WebSocketServer } = require("ws");
 
const server = https.createServer({
  cert: fs.readFileSync("/etc/ssl/cert.pem"),
  key: fs.readFileSync("/etc/ssl/key.pem"),
});
 
const wss = new WebSocketServer({ server });

https.createServer({ cert, key }) membungkus WebSocket dengan TLS. Klien lalu memakai wss:// dan handshake upgrade terjadi di atas koneksi terenkripsi.

Enforce HTTPS

Arahkan semua traffic HTTP biasa ke HTTPS, dan pasang HSTS agar browser tidak pernah mencoba HTTP lagi.

Header HSTS
Strict-Transport-Security: max-age=31536000; includeSubDomains

Header Strict-Transport-Security memberi tahu browser untuk selalu memakai HTTPS ke domain itu selama satu tahun. Ini memblokir serangan downgrade dan man-in-the-middle.

Autentikasi dan Token

Token Berumur Pendek

Token autentikasi untuk WebSocket harus pendek umurnya. JWT dengan masa berlaku berjam-jam memperbesar jendela penyalahgunaan jika bocor. Kombinasi yang baik: akses token singkat untuk koneksi WebSocket, refresh token panjang yang hanya dipakai saat login ulang.

Validasi Origin

Selalu periksa header Origin saat handshake untuk mencegah serangan CSWSH.

JSValidasi origin di server ws
const { WebSocketServer } = require("ws");
 
const wss = new WebSocketServer({
  port: 8080,
  verifyClient: (info) => {
    return info.origin === "https://app.kalian.com";
  },
});

verifyClient(info) memeriksa info.origin sebelum koneksi diterima. Hanya origin terpercaya yang boleh terhubung — ini pertahanan pertama melawan cross-site hijacking.

Input Validation

Sanitasi Semua Input

Setiap pesan yang masuk harus dianggap berbahaya sampai terbukti aman.

JSValidasi dan sanitasi pesan
wss.on("connection", (ws) => {
  ws.on("message", (data) => {
    let pesan;
    try {
      pesan = JSON.parse(data.toString());
    } catch {
      ws.close(1008, "format tidak valid");
      return;
    }
 
    if (typeof pesan.teks !== "string" || pesan.teks.length > 500) {
      ws.close(1008, "pesan terlalu panjang");
      return;
    }
 
    simpanDanKirim(escapeHTML(pesan.teks));
  });
});

Validasi tipe dan panjang sebelum memproses, dan sanitasi output dengan escapeHTML untuk mencegah XSS saat pesan dirender browser. Prinsipnya: terima minim, validasi ketat.

Proteksi dari CSWSH dan DoS

Cross-Site WebSocket Hijacking

CSWSH terjadi saat halaman jahat memaksa browser pengguna membuka WebSocket ke server yang dipercaya. Karena cookie ikut terkirim, server mengira itu koneksi sah. Pertahanannya berlapis:

  • Validasi Origin, seperti contoh di atas.
  • Jangan pernah bergantung pada cookie saja; minta token di handshake.
  • Token harus ada di query string atau handshake auth, bukan hanya cookie.

Anti-DoS

Server yang tanpa batas mudah dilumpuhkan.

JSBatasan anti-DoS
const wss = new WebSocketServer({
  port: 8080,
  maxPayload: 64 * 1024,
  clientTracking: true,
});
 
wss.on("connection", (ws) => {
  if (wss.clients.size > 5000) {
    ws.close(1013, "server penuh");
  }
});

maxPayload: 64 * 1024 membatasi ukuran pesan, dan cek wss.clients.size > 5000 menolak koneksi saat kapasitas penuh. Rate limiting dari episode 13 menambah lapisan berikutnya.

CORS dan Security Header

CORS untuk WebSocket

CORS berlaku saat handshake. Karena WebSocket tidak bisa mengirim header custom di browser, validasi Origin adalah bentuk kontrol utama — pastikan daftar origin yang diizinkan dikelola secara eksplisit, bukan wildcard.

Security Header

Tambahkan header dasar di server HTTP yang melayani halaman aplikasi:

Security header dasar
Content-Security-Policy: default-src 'self'; connect-src 'self' wss://api.kalian.com
X-Frame-Options: DENY
X-Content-Type-Options: nosniff

Content-Security-Policy dengan connect-src secara eksplisit mengizinkan koneksi WebSocket ke domain tertentu dan memblokir lainnya. Ini membatasi kerusakan jika terjadi XSS.

Penutup

Episode 19 menutup celah paling umum aplikasi WebSocket: transport tanpa enkripsi, token yang mudah disalahgunakan, input yang tidak divalidasi, dan koneksi dari origin tak dikenal.

Inti yang harus dibawa pulang:

  • Selalu gunakan wss dengan sertifikat yang valid di production.
  • HSTS dan redirect memaksa semua traffic melewati HTTPS.
  • Token autentikasi harus pendek umurnya dan tidak hanya di cookie.
  • Validasi Origin memblokir CSWSH sejak handshake.
  • Setiap input divalidasi tipe, panjang, dan disanitasi.
  • maxPayload, batas koneksi, dan rate limit melindungi dari DoS.

Di episode 20 berikutnya kita membahas real-time collaboration features: Operational Transformation, CRDT, editing kolaboratif, serta library seperti Yjs dan ShareDB.

Belajar WebSocket - Security Best Practices | Belajar WebSocket