BelajarKoding Logobelajarkoding

Platform belajar web development Indonesia. Artikel, cheat sheets, roadmap, dan code challenges untuk developer Indonesia.

Navigasi

  • Artikel
  • Cheat Sheets
  • Roadmap
  • Challenges
  • Pricing
  • Search

Produk Lain

  • JagoHermes
  • KelasClaude
  • KilatKoding
  • BelajarVibeCoding
  • JualanKoding

Support

  • Privacy Policy
  • Terms of Service
  • Email

© 2026 BelajarKoding. All rights reserved.

Galih PratamaBagian dari ekosistem Galih Pratama
belajarkoding LogobyGalih Pratama
RoadmapArtikelCheat SheetsChallengesUpgrade
belajarkoding LogobyGalih Pratama
RoadmapArtikelCheat SheetsChallengesUpgrade
belajarkoding LogobyGalih Pratama
RoadmapArtikelCheat SheetsChallengesUpgrade

Daftar Isi

Content Security Policy (CSP)Apa Itu CSPDirective Utama CSPContoh CSP HeaderCSP dengan NonceConfig Express.jsConfig Next.js MiddlewareReport-Only ModeStrict-Transport-Security (HSTS)Apa Itu HSTSDirective HSTSContoh HSTS HeaderConfig Express.jsConfig Next.jsX-Frame-OptionsApa Itu X-Frame-OptionsNilai X-Frame-OptionsContoh HeaderConfig Express.jsCatatan tentang frame-ancestors CSPX-Content-Type-OptionsApa Itu X-Content-Type-OptionsContoh HeaderConfig Express.jsConfig Next.jsReferrer-PolicyApa Itu Referrer-PolicyNilai Referrer-PolicyContoh HeaderConfig Express.jsPermissions-PolicyApa Itu Permissions-PolicyContoh HeaderDirective Umum Permissions-PolicyConfig Express.jsNilai DirectiveCross-Origin Headers (CORS)Apa Itu CORSHeader CORSSimple Request vs PreflightConfig Express.js dengan cors PackageCORS Manual tanpa PackageCORS dengan CredentialsCross-Origin Isolation HeadersCOEP, COOP, dan CORPCross-Origin Embedder Policy (COEP)Cross-Origin Opener Policy (COOP)Cross-Origin Resource Policy (CORP)Setup Cross-Origin IsolationConfig Express.jsVerifikasi Isolation di JavaScriptChecklist ImplementasiVerifikasi dengan Helmet (Express)Tool TestingGlossary
SecurityHTTPWeb

Web Security Headers Cheat Sheet

Referensi cepat web security headers. CSP, HSTS, X-Frame-Options, CORS, COEP, COOP, CORP. Perfect buat developer yang mau mengamankan aplikasi web.

JavaScript10 min read1.897 kata
Silakan login atau daftar untuk membaca cheat sheet ini.

Cheat sheet ini berisi kumpulan HTTP security headers yang penting buat melindungi aplikasi web kamu dari serangan umum seperti XSS, clickjacking, MIME sniffing, dan lainnya. Setiap header punya contoh konfigurasi untuk Express.js dan Next.js middleware.

#Content Security Policy (CSP)

#Apa Itu CSP

CSP adalah header yang membatasi sumber daya apa saja (script, style, image, font) yang boleh dimuat oleh browser. Header ini paling efektif untuk mencegah Cross-Site Scripting (XSS) dan data injection attacks.

#Directive Utama CSP

DirectiveFungsi
default-srcDefault policy untuk semua resource type
script-srcSumber JavaScript yang diizinkan
style-srcSumber CSS yang diizinkan
img-srcSumber gambar yang diizinkan
font-srcSumber font yang diizinkan
connect-srcEndpoint fetch, XHR, WebSocket
frame-srcURL iframe yang diizinkan
object-srcPlugin seperti Flash, Java
base-uriURL base yang diizinkan
form-actionEndpoint form submission

#Contoh CSP Header

plaintext
Content-Security-Policy: default-src 'self';
  script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net;
  style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
  font-src 'self' https://fonts.gstatic.com;
  img-src 'self' data: https:;
  connect-src 'self' https://api.example.com;
  frame-ancestors 'none';
  base-uri 'self';
  form-action 'self';
  object-src 'none';

#CSP dengan Nonce

Untuk inline script yang aman, gunakan nonce (number used once) yang di generate setiap request.

plaintext
Content-Security-Policy: script-src 'self' 'nonce-abc123random456';
html
<script nonce="abc123random456">
  console.log("Script ini diizinkan CSP");
</script>

#Config Express.js

javascript
import helmet from "helmet";
 
app.use(
  helmet.contentSecurityPolicy({
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'", "'unsafe-inline'", "https://cdn.jsdelivr.net"],
      styleSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com"],
      fontSrc: ["'self'", "https://fonts.gstatic.com"],
      imgSrc: ["'self'", "data:", "https:"],
      connectSrc: ["'self'", "https://api.example.com"],
      frameAncestors: ["'none'"],
      baseUri: ["'self'"],
      formAction: ["'self'"],
      objectSrc: ["'none'"],
    },
    reportOnly: false,
  })
);

#Config Next.js Middleware

javascript
// middleware.js
export function middleware(request) {
  const nonce = crypto.randomUUID().replace(/-/g, "");
 
  const cspHeader = `
    default-src 'self';
    script-src 'self' 'nonce-${nonce}' 'strict-dynamic';
    style-src 'self' 'unsafe-inline';
    img-src 'self' blob: data: https:;
    font-src 'self';
    connect-src 'self' https://api.example.com;
    frame-ancestors 'none';
    base-uri 'self';
    form-action 'self';
    object-src 'none';
    upgrade-insecure-requests;
  `;
 
  const response = NextResponse.next({
    request: {
      headers: new Headers(request.headers),
    },
  });
 
  response.headers.set("Content-Security-Policy", cspHeader.replace(/\s{2,}/g, " ").trim());
  response.headers.set("x-nonce", nonce);
 
  return response;
}

#Report-Only Mode

Kalau kamu masih testing CSP tanpa blocking, pakai Content-Security-Policy-Report-Only untuk mengirim laporan ke endpoint tanpa memblokir resource.

plaintext
Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report;

#Strict-Transport-Security (HSTS)

#Apa Itu HSTS

HSTS memaksa browser untuk selalu menggunakan HTTPS saat mengakses domain kamu. Ini mencegah serangan SSL stripping dan man-in-the-middle.

#Directive HSTS

DirectiveFungsi
max-ageLama (detik) browser mengingat untuk pakai HTTPS
includeSubDomainsBerlaku untuk semua subdomain
preloadMemungkinkan dimasukkan ke HSTS preload list browser

#Contoh HSTS Header

plaintext
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

#Config Express.js

javascript
app.use(
  helmet.hsts({
    maxAge: 31536000, // 1 tahun dalam detik
    includeSubDomains: true,
    preload: true,
  })
);

#Config Next.js

javascript
// next.config.js
const securityHeaders = [
  {
    key: "Strict-Transport-Security",
    value: "max-age=31536000; includeSubDomains; preload",
  },
];
 
module.exports = {
  async headers() {
    return [
      {
        source: "/(.*)",
        headers: securityHeaders,
      },
    ];
  },
};

#X-Frame-Options

#Apa Itu X-Frame-Options

Header ini mencegah clickjacking dengan mengontrol apakah halaman kamu bisa di embed di iframe.

#Nilai X-Frame-Options

NilaiArti
DENYHalaman tidak bisa di-frame sama sekali
SAMEORIGINHanya boleh di-frame oleh origin yang sama

#Contoh Header

plaintext
X-Frame-Options: DENY

#Config Express.js

javascript
// Helmet sudah set frameguard ke SAMEORIGIN secara default
app.use(
  helmet.frameguard({
    action: "deny", // atau "sameorigin"
  })
);

#Catatan tentang frame-ancestors CSP

Kalau kamu sudah set frame-ancestors di CSP, browser modern akan mengabaikan X-Frame-Options. Tapi tetap disarankan untuk set keduanya demi dukungan browser lama.

#X-Content-Type-Options

#Apa Itu X-Content-Type-Options

Header ini mencegah browser melakukan MIME sniffing, yaitu menebak tipe konten file yang berbeda dari yang di deklarasikan server.

#Contoh Header

plaintext
X-Content-Type-Options: nosniff

#Config Express.js

javascript
app.use(helmet.noSniff()); // Sudah aktif secara default di helmet

#Config Next.js

javascript
const securityHeaders = [
  {
    key: "X-Content-Type-Options",
    value: "nosniff",
  },
];

#Referrer-Policy

#Apa Itu Referrer-Policy

Header ini mengontrol informasi referrer (URL asal) yang dikirim browser saat user mengklik link atau memuat resource dari domain lain.

#Nilai Referrer-Policy

NilaiPerilaku
no-referrerTidak mengirim referrer sama sekali
no-referrer-when-downgradeTidak kirim saat HTTPS ke HTTP (default browser)
same-originHanya kirim referrer ke origin yang sama
originHanya kirim origin, bukan full URL
strict-originHanya kirim origin, tidak saat downgrade
origin-when-cross-originFull URL untuk same-origin, origin saja untuk cross-origin
strict-origin-when-cross-originFull URL same-origin, origin saja cross-origin (default browser modern)
unsafe-urlSelalu kirim full URL (tidak disarankan)

#Contoh Header

plaintext
Referrer-Policy: strict-origin-when-cross-origin

#Config Express.js

javascript
app.use(
  helmet.referrerPolicy({
    policy: ["strict-origin-when-cross-origin"],
  })
);

#Permissions-Policy

#Apa Itu Permissions-Policy

Header ini (dulunya Feature-Policy) mengontrol fitur browser apa saja (kamera, mikrofon, geolocation, payment) yang boleh dipakai oleh halaman kamu dan iframe yang di embed.

#Contoh Header

plaintext
Permissions-Policy: camera=(), microphone=(), geolocation=(self "https://trusted.com"), payment=*

#Directive Umum Permissions-Policy

DirectiveFungsi
cameraAkses kamera
microphoneAkses mikrofon
geolocationAkses lokasi GPS
paymentPayment Request API
fullscreenFullscreen API
usbWebUSB API
clipboard-readBaca clipboard
clipboard-writeTulis clipboard

#Config Express.js

javascript
app.use(
  helmet.permissionsPolicy({
    directives: {
      camera: [],
      microphone: [],
      geolocation: ["self"],
      payment: ["self"],
      fullscreen: ["self"],
    },
  })
);

#Nilai Directive

NilaiArti
()Disabled untuk semua
(self)Hanya untuk origin yang sama
("https://example.com")Hanya untuk origin spesifik
*Enabled untuk semua

#Cross-Origin Headers (CORS)

#Apa Itu CORS

Cross-Origin Resource Sharing (CORS) adalah mekanisme browser yang mengizinkan server menentukan origin mana saja yang boleh mengakses resource-nya. CORS bukan header tunggal tapi kombinasi beberapa header.

#Header CORS

HeaderFungsi
Access-Control-Allow-OriginOrigin mana yang diizinkan
Access-Control-Allow-MethodsHTTP method yang diizinkan
Access-Control-Allow-HeadersCustom header yang diizinkan
Access-Control-Allow-CredentialsBolehkah kirim cookie
Access-Control-Max-AgeCache preflight request (detik)
Access-Control-Expose-HeadersHeader response yang boleh dibaca JS

#Simple Request vs Preflight

Simple request langsung dikirim tanpa preflight jika memenuhi syarat: method GET/HEAD/POST, header hanya yang CORS-safe, dan Content-Type hanya text/plain, multipart/form-data, atau application/x-www-form-urlencoded.

Preflight request dikirim sebagai OPTIONS request sebelum request sebenarnya untuk method seperti PUT/DELETE atau custom header.

#Config Express.js dengan cors Package

javascript
import cors from "cors";
 
// Konfigurasi sederhana
app.use(
  cors({
    origin: "https://example.com", // atau array ["https://a.com", "https://b.com"]
    methods: ["GET", "POST", "PUT", "DELETE"],
    allowedHeaders: ["Content-Type", "Authorization"],
    credentials: true,
    maxAge: 86400,
  })
);
 
// Multiple origins dengan fungsi
app.use(
  cors({
    origin: (origin, callback) => {
      const allowedOrigins = ["https://app.com", "https://admin.app.com"];
      if (!origin || allowedOrigins.includes(origin)) {
        callback(null, true);
      } else {
        callback(new Error("Not allowed by CORS"));
      }
    },
    credentials: true,
  })
);

#CORS Manual tanpa Package

javascript
app.use((req, res, next) => {
  const allowedOrigins = ["https://app.com", "https://admin.app.com"];
  const origin = req.headers.origin;
 
  if (allowedOrigins.includes(origin)) {
    res.setHeader("Access-Control-Allow-Origin", origin);
    res.setHeader("Vary", "Origin");
  }
 
  res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH");
  res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
  res.setHeader("Access-Control-Allow-Credentials", "true");
  res.setHeader("Access-Control-Max-Age", "86400");
 
  if (req.method === "OPTIONS") {
    return res.status(204).end();
  }
 
  next();
});

#CORS dengan Credentials

Kalau kamu set Access-Control-Allow-Credentials: true, maka Access-Control-Allow-Origin tidak boleh *. Harus spesifik origin.

#Cross-Origin Isolation Headers

#COEP, COOP, dan CORP

Tiga header ini dipakai untuk mencapai cross-origin isolation, yang diperlukan untuk fitur seperti SharedArrayBuffer dan high-resolution timers.

#Cross-Origin Embedder Policy (COEP)

Mencegah halaman memuat cross-origin resource yang tidak mengizinkannya.

plaintext
Cross-Origin-Embedder-Policy: require-corp

Nilai:

  • unsafe-none (default): Halaman bisa memuat cross-origin resource tanpa CORP header
  • require-corp: Resource harus set CORP header atau di opt-in lewat crossorigin attribute

#Cross-Origin Opener Policy (COOP)

Mengisolasi browsing context group untuk mencegah serangan seperti Spectre yang mengeksploitasi window references.

plaintext
Cross-Origin-Opener-Policy: same-origin

Nilai:

  • unsafe-none (default): Tidak ada isolasi
  • same-origin-allow-popups: Isolasi tapi boleh window popup
  • same-origin: Isolasi penuh, window references terputus

#Cross-Origin Resource Policy (CORP)

Mengunci resource (image, script, font) hanya untuk origin tertentu.

plaintext
Cross-Origin-Resource-Policy: same-origin

Nilai:

  • same-origin: Hanya origin yang sama bisa memuat
  • same-site: Hanya site yang sama
  • cross-origin: Semua origin boleh (tapi tetap butuh CORS)

#Setup Cross-Origin Isolation

plaintext
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Resource-Policy: same-origin

#Config Express.js

javascript
app.use((req, res, next) => {
  res.setHeader("Cross-Origin-Embedder-Policy", "require-corp");
  res.setHeader("Cross-Origin-Opener-Policy", "same-origin");
  res.setHeader("Cross-Origin-Resource-Policy", "same-origin");
  next();
});

#Verifikasi Isolation di JavaScript

javascript
const isCrossOriginIsolated = self.crossOriginIsolated;
console.log("Cross-origin isolated:", isCrossOriginIsolated);

#Checklist Implementasi

Daftar lengkap header yang harus di set untuk keamanan optimal:

HeaderPrioritasTarget
Content-Security-PolicyTinggiSemua halaman HTML
Strict-Transport-SecurityTinggiSemua HTTPS response
X-Content-Type-OptionsTinggiSemua response
X-Frame-OptionsSedangHalaman sensitif
Referrer-PolicySedangSemua response
Permissions-PolicySedangSemua halaman HTML
Access-Control-Allow-OriginTinggiAPI endpoint cross-origin
COEPOpsionalAplikasi yang butuh SharedArrayBuffer
COOPOpsionalAplikasi yang butuh SharedArrayBuffer

#Verifikasi dengan Helmet (Express)

Helmet secara default mengaktifkan sebagian besar security headers penting. Berikut konfigurasi yang lengkap:

javascript
import helmet from "helset";
 
app.use(
  helmet({
    contentSecurityPolicy: {
      directives: {
        defaultSrc: ["'self'"],
        scriptSrc: ["'self'", "'unsafe-inline'"],
        styleSrc: ["'self'", "'unsafe-inline'"],
        imgSrc: ["'self'", "data:", "https:"],
        connectSrc: ["'self'"],
        frameAncestors: ["'none'"],
        objectSrc: ["'none'"],
      },
    },
    crossOriginEmbedderPolicy: false, // Aktifkan jika butuh SharedArrayBuffer
    crossOriginOpenerPolicy: { policy: "same-origin" },
    crossOriginResourcePolicy: { policy: "same-origin" },
    hsts: {
      maxAge: 31536000,
      includeSubDomains: true,
      preload: true,
    },
    frameguard: { action: "deny" },
    noSniff: true,
    referrerPolicy: { policy: "strict-origin-when-cross-origin" },
    permissionsPolicy: {
      directives: {
        camera: [],
        microphone: [],
        geolocation: ["self"],
        payment: ["self"],
      },
    },
  })
);

#Tool Testing

Gunakan tool berikut untuk audit security headers:

  • securityheaders.com: Ketik URL untuk grade A+
  • Observatory by Mozilla: Audit lengkap
  • Browser DevTools: Tab Network, klik response, lihat Headers
  • Lighthouse: Bagian Best Practices

#Glossary

  • CSP (Content Security Policy): Header yang membatasi sumber daya yang bisa dimuat browser untuk mencegah XSS dan injection.
  • HSTS (HTTP Strict Transport Security): Header yang memaksa browser selalu pakai HTTPS.
  • Clickjacking: Serangan di mana attacker mengembed halaman korban di iframe transparan dan menipu user untuk klik.
  • MIME Sniffing: Browser menebak tipe konten file berbeda dari deklarasi server, bisa dieksploitasi untuk menjalankan script.
  • CORS (Cross-Origin Resource Sharing): Mekanisme yang mengizinkan server menentukan origin mana yang boleh akses resource-nya.
  • Preflight Request: Request OPTIONS yang dikirim browser sebelum request sebenarnya untuk memeriksa izin CORS.
  • COEP (Cross-Origin Embedder Policy): Header yang mencegah halaman memuat cross-origin resource tanpa izin.
  • COOP (Cross-Origin Opener Policy): Header yang mengisolasi browsing context untuk mencegah serangan side-channel.
  • CORP (Cross-Origin Resource Policy): Header yang mengunci resource hanya untuk origin tertentu.
  • Nonce: Angka acak yang di generate sekali per request untuk mengizinkan inline script di CSP.
  • Cross-Origin Isolation: Status saat halaman mencapai isolasi penuh lewat COEP dan COOP, memungkinkan SharedArrayBuffer.
  • Origin: Skema, host, dan port sebuah URL (contoh: https://example.com).
  • Same-Origin: Skema, host, dan port sama persis.
  • Same-Site: Domain registrable sama (contoh: app.example.com dan api.example.com).

Baca Cheat Sheet Lengkap

Login atau daftar akun gratis untuk membaca cheat sheet ini.

LoginDaftar Gratis
Share: