CSP cho Nginx & Apache: ‘Khiên’ chống XSS cực mạnh cho Website

Security tutorial - IT technology blog
Security tutorial - IT technology blog

Tại sao bảo mật không bao giờ là thừa?

Nói thiệt với anh em, cái tính cẩn thận của mình về bảo mật cũng từ “xương máu” mà ra. Hồi mới vào nghề, mình từng thức trắng tới 3 giờ sáng vì server bị brute-force với hơn 10.000 request mỗi giờ. Cảm giác lúc đó thốn lắm, tim đập chân run vì sợ lộ dữ liệu khách hàng. Sau vố đau đó, mình rút ra bài học: bảo mật phải chuẩn ngay từ đầu. Một trong những món “vũ khí” lợi hại nhất chính là Content Security Policy (CSP).

Hãy tưởng tượng website của bạn giống như một ngôi nhà. SSL/HTTPS là chiếc khóa cửa chính chắc chắn. Tuy nhiên, nếu lỗ hổng XSS vẫn tồn tại, cửa sổ nhà bạn coi như đang mở toang. Kẻ trộm có thể dễ dàng ném “thuốc độc” (script độc hại) vào bên trong bất cứ lúc nào. CSP đóng vai trò như lớp lưới bảo vệ cửa sổ. Nó chỉ cho phép những gì bạn tin tưởng mới được phép hoạt động.

Hai cách tiếp cận triển khai CSP phổ biến

Thực tế hiện nay, anh em thường có hai con đường chính để thiết lập CSP. Mỗi cách sẽ phù hợp với từng môi trường server khác nhau.

1. Chèn thẻ Meta vào HTML

Cách này cực kỳ nhanh gọn. Anh em chỉ cần thêm một dòng code vào phần <head> của trang web là xong.

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' https://apis.google.com;">

2. Cấu hình trực tiếp qua HTTP Header (Nginx/Apache)

Đây là phương án dành cho dân chuyên. Thay vì để trình duyệt tìm trong file HTML, server sẽ chủ động gửi chỉ thị bảo mật ngay khi trả về dữ liệu. Theo báo cáo từ HackerOne, XSS chiếm hơn 23% tổng số tiền thưởng bug bounty toàn cầu. Việc cấu hình ở tầng server giúp bạn kiểm soát rủi ro này triệt để hơn.

Mổ xẻ ưu và nhược điểm

Để anh em dễ chọn lựa, mình sẽ phân tích nhanh thế mạnh của từng ông:

  • Thẻ Meta HTML:
    • Ưu điểm: Triển khai nhanh, không cần quyền root server, cực hợp cho anh em dùng share host.
    • Nhược điểm: Khó quản lý khi web có hàng nghìn trang. Đặc biệt, nó không hỗ trợ tính năng report-uri để báo cáo vi phạm về server.
  • HTTP Header từ Web Server:
    • Ưu điểm: Áp dụng đồng bộ toàn trang chỉ với vài dòng config. Hỗ trợ đầy đủ mọi tính năng cao cấp của CSP. Độ bảo mật cao hơn vì nằm ở lớp vận chuyển.
    • Nhược điểm: Cần quyền sửa file cấu hình hệ thống. Nếu viết sai cú pháp, các script quan trọng như Google Maps hay Facebook Pixel sẽ bị chặn sạch.

Lý do mình luôn ưu tiên cấu hình trên Web Server

Với kinh nghiệm cá nhân, mình khuyên anh em nên chọn cấu hình server vì tính tập trung. Khi cần thêm một domain ảnh mới, bạn chỉ cần sửa đúng một chỗ duy nhất. Bạn sẽ không phải đi lục lọi từng file HTML để cập nhật nữa. Ngoài ra, gửi CSP qua Header giúp giảm tải cho việc phân giải HTML và nhìn “xịn” hơn hẳn khi audit bằng Lighthouse.

Thực hành cấu hình trên Nginx và Apache

Một chính sách CSP an toàn thường gồm các chỉ thị cơ bản sau:

  • default-src 'self': Chỉ load tài nguyên từ chính domain của mình.
  • script-src 'self': Chỉ cho phép script nội bộ chạy.
  • img-src 'self' data:: Cho phép ảnh nội bộ và ảnh base64.
  • style-src 'self' 'unsafe-inline': Cho phép CSS nội bộ (nên hạn chế dùng unsafe-inline nếu có thể).

1. Setup cho Nginx

Mở file config domain của bạn và thêm dòng sau vào block server:

server {
    listen 443 ssl;
    server_name itfromzero.com;

    # Cấu hình CSP chuẩn
    add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://www.google-analytics.com; img-src 'self' https://images.unsplash.com; style-src 'self' 'unsafe-inline'; font-src 'self' https://fonts.gstatic.com;" always;
}

Đừng quên check lại cú pháp trước khi restart:

sudo nginx -t && sudo systemctl restart nginx

2. Setup cho Apache

Trước tiên, hãy đảm bảo module headers đã được bật bằng lệnh sudo a2enmod headers. Sau đó, thêm đoạn này vào file .htaccess:

<IfModule mod_headers.c>
    Header set Content-Security-Policy "default-src 'self'; script-src 'self' https://www.google-analytics.com; img-src 'self'; style-src 'self';"
</IfModule>

Lưu ý sống còn để tránh “sập” giao diện

Nhiều anh em vừa bật CSP xong là web trắng tinh. Nguyên nhân thường do CSP quá chặt, chặn luôn cả script hợp lệ mà bạn quên khai báo. Mẹo nhỏ là hãy dùng Content-Security-Policy-Report-Only trước. Chế độ này không chặn tài nguyên mà chỉ log lại các vi phạm vào Console để bạn theo dõi.

# Test thử trên Nginx
add_header Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self';";

Công cụ kiểm tra độ chuẩn chỉ của CSP

Cấu hình xong rồi thì phải check cho chắc cú bằng các công cụ sau:

  1. F12 Console: Nếu thấy lỗi đỏ liên quan đến “CSP directive”, bạn đang chặn nhầm thứ gì đó rồi.
  2. Google CSP Evaluator: Giúp soi lỗi hổng trong chính sách bạn vừa viết.
  3. SecurityHeaders.com: Nhập URL vào để chấm điểm bảo mật. Hãy cố gắng đạt điểm A+ nhé.

Làm bảo mật hơi cực vì phải cân chỉnh nhiều. Nhưng thà tốn công lúc đầu, còn hơn một ngày đẹp trời thấy website bị chèn link cá độ hay đào coin lén.

Share: