Tạo HTTP Security Header
Xây dựng Content-Security-Policy, kiểm tra rủi ro của policy có sẵn, tính hash cho script inline, chọn giá trị khuyên dùng cho HSTS, Permissions-Policy và các header bảo mật khác, rồi xuất thành cấu hình dán thẳng vào server hoặc hosting. Tab cuối có công cụ tạo và kiểm tra file security.txt.
Các bước
- Mở tab Content-Security-Policy. Ở chế độ Trình tạo, bắt đầu từ một mẫu: Nghiêm ngặt (dùng nonce) và Next.js / React SPA thay toàn bộ policy, còn + Google Analytics / GTM, + Nhúng YouTube và + Stripe thêm các host mà dịch vụ đó cần vào policy hiện có.
- Chỉnh từng directive: chọn nguồn như
'self'hayhttps:trong danh sách, hoặc gõ host rồi nhấn Enter. Thẻ Policy hiện header hoàn chỉnh kèm tóm tắt mức độ rủi ro; Chi tiết mở nó trong mục Phân tích. - Lần triển khai đầu tiên, hãy bật Chế độ Report-Only — trình duyệt chỉ báo cáo vi phạm mà không chặn gì.
- Đã có sẵn policy? Chuyển sang Phân tích và dán vào — policy trần, dòng header
Content-Security-Policy:hay thẻ<meta>đều được. Đọc Kết quả phân tích, rồi bấm Sửa trong trình tạo để sửa. - Với khối
<script>hoặc<style>inline không chuyển ra file được, mở Tạo hash, dán đúng phần code nằm giữa hai thẻ rồi bấm Thêm vào script-src (hoặc Thêm vào style-src). - Ở tab Header khác, bật các header bạn cần và chọn giá trị. Strict-Transport-Security có sẵn Danh sách kiểm tra hstspreload.org; Permissions-Policy có nút Khuyên dùng và bảng chỉnh từng tính năng.
- Mở Cấu hình server, chọn định dạng — Header thô, Nginx, Apache .htaccess, Next.js, Express / helmet, Vercel, Netlify _headers, Cloudflare Workers hoặc IIS web.config — rồi Sao chép hoặc Tải xuống.
- Ở tab security.txt, chọn Tạo file (bắt buộc có Contact và Expires; phần kiểm tra bên dưới liệt kê lỗi nếu có) hoặc Kiểm tra file để soát file bạn đang dùng.
Mẹo
- Nonce phải là giá trị ngẫu nhiên mới cho mỗi response. File cấu hình tĩnh của nginx, Apache, vercel.json hay next.config không làm được việc đó, nên CSP dùng nonce phải được đặt từ middleware, Worker hoặc ứng dụng — các header còn lại để tĩnh được.
- Trong mẫu nghiêm ngặt,
'unsafe-inline'vàhttps:là dự phòng có chủ đích: trình duyệt hiểu nonce và'strict-dynamic'sẽ bỏ qua cả hai, nên bộ phân tích không báo lỗi chúng. camera=()trong Permissions-Policy tắt camera cả với chính trang của bạn. Nếu site quét mã QR, ghi âm hay chia sẻ màn hình, hãy cho phép(self)với camera, microphone hoặcdisplay-capture(một tính năng riêng).preloadcủa HSTS rất khó gỡ. Bắt đầu với max-age ngắn, xác nhận mọi tên miền con chạy HTTPS, rồi tăng lên từ một năm trở lên trước khi gửi lên hstspreload.org.- Hãy gửi cả
frame-ancestorslẫn X-Frame-Options: trình duyệt mới dùng directive của CSP, trình duyệt cũ chỉ đọc header. Giữ chúng khớp nhau — DENY đi với'none', SAMEORIGIN đi với'self'. - Trong nginx,
add_headerđặt trong khốilocationsẽ bỏ hết cácadd_headerkế thừa từserver, nên phải lặp lại các header bảo mật ở đó. - Hash của script inline tính trên từng byte giữa hai thẻ. Nếu template thêm thụt lề hay dấu xuống dòng cuối, hash của đoạn code bạn dán sẽ không khớp với bản thật.
- security.txt phải có Expires dưới một năm; hãy đặt lịch nhắc gia hạn ngay hôm đăng file.
Câu hỏi thường gặp
CSP nghiêm ngặt có làm hỏng trang của tôi không?
Có thể, vì vậy công cụ có Chế độ Report-Only. Những chỗ hay hỏng là event handler onclick inline, style inline, widget bên thứ ba được tải mà không có nonce và eval() trong thư viện cũ hoặc bản build development. Hãy triển khai header Report-Only, xem báo cáo, rồi chuyển code inline ra file, thêm nonce hoặc hash, hay cho phép đúng host cần thiết — khi báo cáo đã yên thì chuyển sang chế độ áp dụng.
Nội dung tôi dán có bị gửi lên server không?
Không. Việc đọc, phân tích, tính hash và tạo cấu hình đều chạy hoàn toàn trong trình duyệt. Công cụ không bao giờ truy cập website của bạn — nó chỉ tạo văn bản để bạn sao chép. Tự kiểm tra header thật bằng curl -sI https://site-cua-ban.
Vì sao trình duyệt không nhận hash 'sha256-…' của tôi?
Hash phải được tính trên đúng các ký tự trình duyệt nhận được giữa hai thẻ, kể cả dấu cách, tab và xuống dòng. Hãy copy khối code từ HTML thật (view-source), không phải từ template, và để ý ký tự xuống dòng kiểu Windows — công cụ sẽ cảnh báo khi có khoảng trắng ở đầu/cuối hoặc CRLF.
Đã đặt frame-ancestors thì còn cần X-Frame-Options không?
Trình duyệt hỗ trợ CSP Level 2 bỏ qua X-Frame-Options khi có frame-ancestors, nhưng gửi cả hai chẳng tốn gì mà vẫn bảo vệ được trình duyệt cũ. frame-ancestors không có tác dụng trong thẻ <meta>, nên nó phải đến từ HTTP header thật.