Security Headers

Security Headers #

HTTP security headers adalah instruksi yang dikirim server ke browser untuk mengaktifkan mekanisme keamanan bawaan browser. Mereka tidak melindungi dari semua jenis serangan, tapi menutup sejumlah celah yang sering dieksploitasi — XSS, clickjacking, MIME sniffing, dan lainnya — hanya dengan beberapa baris konfigurasi.

X-Frame-Options: Cegah Clickjacking #

Clickjacking adalah teknik di mana halaman kamu di-embed dalam iframe di situs lain, lalu pengguna ditipu untuk mengklik elemen di situsmu tanpa menyadarinya.

# SAMEORIGIN: hanya izinkan iframe dari domain yang sama
add_header X-Frame-Options "SAMEORIGIN" always;

# DENY: larang iframe sepenuhnya dari mana pun
# add_header X-Frame-Options "DENY" always;

SAMEORIGIN cocok untuk sebagian besar aplikasi. Gunakan DENY jika situsmu tidak pernah perlu di-embed dalam iframe sama sekali.


X-Content-Type-Options: Cegah MIME Sniffing #

Browser kadang “menebak” tipe konten berdasarkan isinya, mengabaikan Content-Type header. Ini bisa berbahaya — misalnya browser mengeksekusi file teks sebagai JavaScript.

add_header X-Content-Type-Options "nosniff" always;

Dengan nosniff, browser mengikuti Content-Type yang dikirim server dan tidak mencoba menebak sendiri. Selalu aktifkan ini.


Referrer-Policy: Kontrol Kebocoran URL #

Saat pengguna mengklik link ke situs lain, browser secara default mengirim URL halaman asal dalam header Referer. Ini bisa membocorkan informasi sensitif yang ada di URL (token di query string, path internal).

# strict-origin-when-cross-origin: kirim full URL untuk same-origin,
# hanya origin (tanpa path) untuk cross-origin HTTPS,
# tidak kirim apapun untuk cross-origin HTTP
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

# no-referrer: tidak pernah kirim referrer apapun
# add_header Referrer-Policy "no-referrer" always;

strict-origin-when-cross-origin adalah nilai yang direkomendasikan — keseimbangan antara privasi dan fungsionalitas analitik.


X-XSS-Protection #

Header ini mengaktifkan filter XSS bawaan di browser lama (IE, Chrome lama). Browser modern sudah tidak menggunakannya (CSP jauh lebih efektif), tapi masih berguna untuk backward compatibility:

add_header X-XSS-Protection "1; mode=block" always;

mode=block memerintahkan browser untuk memblokir seluruh halaman jika XSS terdeteksi, alih-alih mencoba “membersihkan” kontennya.


Permissions-Policy: Kontrol Akses Fitur Browser #

Permissions-Policy (sebelumnya disebut Feature-Policy) mengontrol fitur browser mana yang bisa digunakan oleh halaman atau iframe yang di-embed:

add_header Permissions-Policy
    "camera=(), microphone=(), geolocation=(), payment=(), usb=()"
    always;

Nilai () berarti fitur tersebut dinonaktifkan untuk semua origin. Berguna untuk mencegah iframe dari situs lain mengakses kamera atau mikrofon pengguna.


Content Security Policy (CSP) #

CSP adalah yang paling powerful sekaligus paling kompleks. Ia mendefinisikan dari mana sumber daya (script, style, gambar, font) boleh dimuat — mencegah browser mengeksekusi skrip yang tidak diizinkan, yang merupakan mitigasi XSS paling efektif.

# CSP yang ketat — hanya izinkan resource dari domain sendiri
add_header Content-Security-Policy
    "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' https://fonts.gstatic.com; connect-src 'self'; frame-ancestors 'none';"
    always;

CSP bisa sangat membatasi dan memerlukan penyesuaian yang signifikan tergantung stack frontend yang digunakan. Cara yang aman untuk memulai adalah dengan mode report-only:

# Report-only: pelanggaran dilaporkan tapi tidak diblokir
# Berguna untuk audit sebelum enforce
add_header Content-Security-Policy-Report-Only
    "default-src 'self'; report-uri /csp-report"
    always;

Menyatukan Semua dalam Snippet #

Karena security headers biasanya sama untuk semua location, lebih baik dijadikan snippet:

# /etc/nginx/snippets/security-headers.conf
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;

# HSTS — uncomment setelah yakin semua subdomain siap HTTPS
# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

Kemudian di setiap server block:

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    include snippets/security-headers.conf;

    location / {
        # Ingat: jika location ini mendefinisikan add_header sendiri,
        # ia tidak mewarisi dari server block.
        # Solusi: include snippet lagi di sini.
        include snippets/security-headers.conf;
        add_header Cache-Control "no-store" always;
        proxy_pass http://backend;
    }
}

Mengecek Security Headers #

# Cek headers yang dikirim server
curl -I https://example.com

# Atau gunakan tools online:
# https://securityheaders.com — berikan rating A-F dan penjelasan
# https://observatory.mozilla.org — analisis komprehensif

securityheaders.com adalah cara cepat untuk melihat header mana yang sudah ada dan mana yang masih kurang.


Ringkasan #

  • X-Frame-Options: SAMEORIGIN — cegah clickjacking dengan melarang embed di iframe dari domain lain.
  • X-Content-Type-Options: nosniff — paksa browser ikuti Content-Type yang dikirim server, jangan tebak sendiri.
  • Referrer-Policy: strict-origin-when-cross-origin — cegah kebocoran URL sensitif ke situs lain.
  • CSP adalah proteksi XSS paling efektif — mulai dengan Content-Security-Policy-Report-Only untuk audit sebelum enforce.
  • Taruh semua security headers dalam snippet yang di-include di setiap server block — ingat jebakan inheritance add_header jika ada location yang mendefinisikan header sendiri.

← Sebelumnya: Proteksi DoS   Berikutnya: Access Log →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact