JavaScript Security: XSS, CSRF, dan Strategi Pencegahannya

JavaScript Security: XSS, CSRF, dan Strategi Pencegahannya

JavaScript memungkinkan interaktivitas dinamis di website, tetapi rentan terhadap serangan keamanan seperti Cross-Site Scripting (XSS) dan Cross-Site Request Forgery (CSRF). Kesalahan keamanan ini bisa menyebabkan:

  • Pencurian data pengguna
  • Manipulasi konten website
  • Kerugian bisnis dan reputasi

Artikel ini membahas secara mendalam XSS, CSRF, contoh nyata serangan, dan strategi pencegahan efektif.


1. Cross-Site Scripting (XSS)

1.1 Apa itu XSS

XSS terjadi ketika attacker menyisipkan script jahat ke website yang dijalankan di browser pengguna.

Tipe XSS:

  1. Reflected XSS – script terkirim melalui URL atau input form, dieksekusi seketika.
  2. Stored XSS – script tersimpan di server (misal database) → dieksekusi setiap ada user mengakses halaman.
  3. DOM-based XSS – script dieksekusi sepenuhnya di browser, manipulasi DOM.

1.2 Contoh Reflected XSS

Scenario: search query di website tidak disanitasi.

// search.js
const params = new URLSearchParams(window.location.search);
document.getElementById('results').innerHTML = params.get('q');

Serangan:

https://example.com/search?q=<script>alert('XSS')</script>

Akibat:

  • Browser mengeksekusi alert('XSS')
  • Bisa diganti script berbahaya untuk mencuri cookie atau token

1.3 Contoh Stored XSS

Scenario: komentar user tidak disanitasi.

// server.js
app.post('/comment', (req, res) => {
  db.save(req.body.comment); // tidak sanitize
});

Serangan:

  • User menyisipkan <script>document.cookie</script> → setiap orang yang melihat komentar akan mengeksekusi script → cookie dicuri

1.4 Contoh DOM-based XSS

// script.js
const hash = window.location.hash;
document.getElementById('content').innerHTML = hash.substring(1);

Serangan:

https://example.com/#<img src=x onerror=alert(1)>
  • Script dieksekusi di browser sepenuhnya tanpa melewati server

1.5 Pencegahan XSS

  1. Sanitize input user
    • Gunakan library: DOMPurify, xss-filters
    const clean = DOMPurify.sanitize(userInput); document.getElementById('results').innerHTML = clean;
  2. Escape output
    • Jangan langsung gunakan innerHTML, gunakan textContent jika bisa
  3. Content Security Policy (CSP)
    • Batasi sumber script yang diperbolehkan
    Content-Security-Policy: default-src 'self'; script-src 'self'
  4. Hindari eval / new Function
    • Jangan mengeksekusi JS dari input user
  5. Validate & encode input di server
    • Selalu lakukan sanitasi di backend sebelum menyimpan ke database

2. Cross-Site Request Forgery (CSRF)

2.1 Apa itu CSRF

CSRF terjadi ketika attacker memaksa user melakukan request ke server yang sah menggunakan sesi atau cookie yang masih aktif.

Contoh nyata:

  • User login di bank.com → attacker membuat <img src="https://bank.com/transfer?amount=1000&to=attacker">
  • Browser otomatis mengirim request dengan cookie → transfer uang terjadi

2.2 Pencegahan CSRF

  1. CSRF Token
    • Setiap form atau request memiliki token unik.
<form method="POST" action="/transfer">
  <input type="hidden" name="csrf_token" value="UNIQUE_TOKEN_HERE">
  <input type="submit" value="Transfer">
</form>
  • Server validasi token sebelum memproses request
  1. SameSite Cookies
    • Batasi cookie agar hanya dikirim ke request dari domain yang sama
Set-Cookie: sessionId=abc123; SameSite=Strict; Secure
  1. Custom Headers / Double Submit Cookie
    • AJAX request wajib menyertakan header khusus → server cek kesesuaian
  2. Validasi HTTP Referer / Origin
    • Pastikan request berasal dari domain yang sah

3. Contoh Nyata Implementasi XSS + CSRF Protection

// Express + CSRF Middleware
const express = require('express');
const csurf = require('csurf');
const bodyParser = require('body-parser');
const DOMPurify = require('dompurify');

const app = express();
const csrfProtection = csurf({ cookie: true });

app.use(bodyParser.urlencoded({ extended: false }));
app.use(require('cookie-parser')());

// Form route
app.get('/comment', csrfProtection, (req, res) => {
  res.send(`
    <form method="POST">
      <input type="hidden" name="_csrf" value="${req.csrfToken()}">
      <textarea name="comment"></textarea>
      <button type="submit">Submit</button>
    </form>
  `);
});

// Process comment
app.post('/comment', csrfProtection, (req, res) => {
  const sanitizedComment = DOMPurify.sanitize(req.body.comment);
  db.save(sanitizedComment);
  res.send('Comment saved safely!');
});

Keunggulan:

  • XSS dicegah dengan DOMPurify.sanitize
  • CSRF dicegah dengan token unik di setiap form

4. Best Practice JavaScript Security Production

  1. Selalu sanitize input & escape output
  2. Gunakan HTTPS untuk semua request → lindungi cookie dan token
  3. Content Security Policy (CSP) → batasi script dari sumber luar
  4. Gunakan CSRF Token atau SameSite cookies
  5. Hindari eval / innerHTML langsung dari input user
  6. Audit third-party scripts → library eksternal bisa menjadi vektor XSS
  7. Gunakan security headers tambahan:
    • X-Content-Type-Options: nosniff
    • X-Frame-Options: DENY
    • Strict-Transport-Security: max-age=31536000; includeSubDomains

5. Studi Kasus Nyata

5.1 E-Commerce Comment Section (Stored XSS)

  • Masalah: komentar user tidak disanitasi → attacker sisipkan <script>document.cookie</script>
  • Dampak: setiap visitor website → cookie dicuri → session hijacking
  • Solusi: sanitize input dengan DOMPurify + CSP
  • Hasil: XSS dicegah, website aman, SEO & UX stabil

5.2 Banking Transfer Form (CSRF)

  • Masalah: attacker buat form fake → user login → transfer otomatis
  • Solusi: implement CSRF token + SameSite cookie
  • Hasil: setiap request diverifikasi → serangan CSRF gagal

6. Checklist JavaScript Security

  • Sanitize & escape semua input user
  • Gunakan textContent daripada innerHTML bila memungkinkan
  • Implement CSP → batasi sumber script
  • Gunakan CSRF Token / SameSite cookie untuk request sensitif
  • Audit semua library pihak ketiga
  • Hindari eval / dynamic JS dari input user
  • Gunakan HTTPS & security headers

7. Kesimpulan

XSS dan CSRF adalah dua vektor serangan utama JavaScript yang dapat merusak website dan mencuri data pengguna.

Dengan:

  • Sanitasi input
  • Escape output
  • CSP
  • CSRF token / SameSite cookie
  • HTTPS & security headers

…website menjadi aman, SEO-friendly, dan stabil untuk user.

Implementasi praktis & production-ready seperti contoh Express + DOMPurify + CSRF Token akan melindungi aplikasi dari serangan umum, sambil tetap menjaga UX dan performa.