blog.dopana

Back

Security headers là lớp bảo vệ đầu tiên chống lại nhiều tấn công web phổ biến. Nhiều header chỉ là 1 dòng config — nhưng hiệu quả rất lớn.

Content Security Policy (CSP)#

CSP kiểm soát resource nào được load trên trang — chống XSS và data injection mạnh nhất.

Cấu Trúc#

Content-Security-Policy: default-src 'self'; script-src 'self' https://analytics.example.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https://images.example.com
http

Directives#

CSP Report Only#

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

Chỉ report, không block — dùng để test CSP mới trước khi enforce.

Nounce & Hash#

<!-- Nonce — random token mỗi request -->
<script nonce="abc123">
  inlineScript();
</script>
html
Content-Security-Policy: script-src 'nonce-abc123'
http
<!-- Hash — hash của inline script -->
<script>
  inlineScript();
</script>
html
Content-Security-Policy: script-src 'sha256-abc123...'
http

Strict Transport Security (HSTS)#

Yêu cầu trình duyệt chỉ dùng HTTPS — không bao giờ dùng HTTP:

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
http
DirectiveÝ nghĩa
max-age=315360001 năm — nhớ chỉ dùng HTTPS
includeSubDomainsÁp dụng cho subdomain
preloadĐưa vào HSTS preload list (Chrome, Firefox)

Preload#

Khi preload được set và domain được submit vào hstspreload.org — browser built-in list, không bao giờ cho phép HTTP ngay cả lần đầu.

X-Frame-Options#

Chống clickjacking — không cho trang web bị iframe:

X-Frame-Options: DENY
# hoặc
X-Frame-Options: SAMEORIGIN
http

CSP tương đương: frame-ancestors 'self' (CSP mạnh hơn, nên dùng CSP thay vì X-Frame-Options).

X-Content-Type-Options#

Chống MIME type sniffing — browser không tự đoán content type:

X-Content-Type-Options: nosniff
http

Nếu không có header này, browser có thể đọc file .txt như HTML và chạy script.

Referrer-Policy#

Kiểm soát thông tin referrer gửi đi:

Referrer-Policy: strict-origin-when-cross-origin
http
PolicyMô tả
no-referrerKhông gửi referrer
same-originChỉ gửi khi cùng origin
strict-origin-when-cross-origin(Mặc định) Gửi full URL cho same-origin, chỉ origin cho cross-origin, không gửi khi HTTPS→HTTP
no-referrer-when-downgradeGửi full URL, trừ khi HTTPS→HTTP

Permissions-Policy (Feature Policy)#

Kiểm soát API browser được phép dùng:

Permissions-Policy: camera=(), microphone=(), geolocation=(self "https://maps.example.com"), payment=()
http
# Chặn tất cả
Permissions-Policy: camera=(), microphone=(), geolocation=()

# Cho phép một số origin
Permissions-Policy: geolocation=(self "https://maps.example.com"), usb=()

# Cho phép tất cả (không khuyến nghị)
Permissions-Policy: camera=*
http

Cross-Origin-Read-Block (CORB) & COOP/COEP#

Cross-Origin-Opener-Policy (COOP)#

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

Isolate trang khỏi cross-origin — chống Spectre attack.

Cross-Origin-Embedder-Policy (COEP)#

Cross-Origin-Embedder-Policy: require-cors
http

Yêu cầu cross-origin resource phải có CORS header — cho phép dùng SharedArrayBuffer.

Cross-Origin-Resource-Policy (CORP)#

Cross-Origin-Resource-Policy: same-origin
# hoặc same-site, cross-origin
http

Cache Headers#

# Static assets — cache dài
Cache-Control: public, max-age=31536000, immutable

# HTML — không cache
Cache-Control: no-cache, no-store, must-revalidate

# API response — cache có thời hạn
Cache-Control: private, max-age=300
http

Implementation — Express#

Implementation — Cloudflare Workers#

Check Security Headers#

# Curl
curl -I https://example.com | grep -i security

# Online tools
# https://securityheaders.com
# https://csp-evaluator.withgoogle.com
bash

Checklist#

  • Content-Security-Policy (CSP) — chống XSS
  • Strict-Transport-Security (HSTS) — HTTPS bắt buộc
  • X-Content-Type-Options: nosniff
  • X-Frame-Options: DENY hoặc CSP frame-ancestors
  • Referrer-Policy: strict-origin-when-cross-origin
  • Permissions-Policy: thu hẹp API access
  • Cache-Control: phù hợp cho từng loại resource
  • Set-Cookie: có HttpOnly, Secure, SameSite

Kết Luận#

Security headers là low-effort, high-impact. Mất 10 phút để config — bảo vệ chống XSS, clickjacking, MIME sniffing, và nhiều tấn công khác. Dùng Helmet (Node.js) hoặc tự set headers trong Workers/nginx. Kiểm tra với securityheaders.com.

Tài liệu tham khảo#