Tăng cường bảo mật Nginx: Ngăn chặn Clickjacking và Injection với CSP, HSTS và Permissions-Policy

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

Những lỗ hổng tiềm ẩn trong cấu hình Nginx mặc định

Nhận được phản hồi “200 OK” từ một thiết lập Nginx mới mang lại cảm giác rất tuyệt vời. Tôi đã từng ở trong tình huống đó nhiều lần. Tuy nhiên, một tín hiệu đèn xanh không có nghĩa là máy chủ của bạn đã an toàn. Nếu bạn giữ nguyên các thiết lập mặc định, về cơ bản bạn đang để cửa trước mở toang. Điều này khiến người dùng của bạn dễ bị tấn công Clickjacking và Cross-Site Scripting (XSS), vốn chiếm gần 40% các lỗ hổng web được tìm thấy trong các báo cáo bug bounty gần đây.

Bảo mật hiện đại đã phát triển. Nó không còn chỉ xoay quanh mã nguồn backend của bạn trong Python hay Node.js nữa. Giờ đây, bạn phải chủ động quản lý cách trình duyệt tương tác với nội dung của mình. Các security header đóng vai trò như những chỉ dẫn cụ thể cho trình duyệt của khách truy cập. Chúng xác định cái gì đáng tin và cái gì cần chặn. Nếu không có chúng, trình duyệt sẽ mặc định rằng mọi script và iframe đều an toàn, và đó là một sai lầm nguy hiểm.

Tôi từng làm việc trong một dự án đối mặt với một cuộc tấn công Clickjacking tinh vi. Kẻ tấn công đã nhúng trang đăng nhập của chúng tôi vào một iframe ẩn trên một trang web “Tặng thẻ quà tặng miễn phí”. Người dùng nghĩ rằng họ đang nhấp vào nút nhận thưởng, nhưng thực tế họ đang gửi thông tin đăng nhập vào form của chúng tôi. Sự cố đó đã chứng minh rằng logic phía server chỉ là một nửa cuộc chiến. Bạn phải kiểm soát hành vi của trình duyệt thông qua các HTTP header.

Các khái niệm cốt lõi: Bộ công cụ Security Header của bạn

Trước khi chỉnh sửa tệp cấu hình, bạn cần biết công cụ nào là quan trọng nhất. Ba header cụ thể sau đây đóng vai trò then chốt khi tăng cường bảo mật Nginx: HSTS, CSP và Permissions-Policy.

1. HSTS (HTTP Strict Transport Security)

HSTS buộc trình duyệt chỉ giao tiếp qua HTTPS. Ngay cả khi người dùng nhập http://, trình duyệt sẽ thực hiện chuyển hướng nội bộ trước khi yêu cầu rời khỏi máy tính. Điều này loại bỏ hiệu quả các cuộc tấn công Man-in-the-Middle (MITM) và ngăn chặn “SSL Stripping”. Nó cũng giúp tiết kiệm khoảng 50ms độ trễ bằng cách bỏ qua bước chuyển hướng 301 phía server.

2. CSP (Content Security Policy)

CSP là lá chắn mạnh nhất của bạn chống lại XSS. Nó cho phép bạn tạo một danh sách trắng (whitelist) các nguồn đáng tin cậy cho script, style và hình ảnh. Nếu một hacker cố gắng tải một script độc hại từ một CDN bên ngoài mà bạn chưa phê duyệt, trình duyệt sẽ đơn giản là chặn việc thực thi đó.

3. Permissions-Policy

Header này hạn chế những tính năng phần cứng nào mà trang web của bạn có thể sử dụng. Nếu ứng dụng của bạn không cần camera, micro hoặc định vị địa lý, hãy tắt hoàn toàn chúng. Điều này giới hạn “bề mặt tấn công” (attack surface) của bạn. Nếu một lỗ hổng bị phát hiện trong mã nguồn frontend, kẻ tấn công vẫn sẽ không thể theo dõi người dùng của bạn.

Thực hành: Cấu hình Nginx

Trước khi chạm vào cấu hình production, hãy đảm bảo thông tin quản trị của bạn cực kỳ vững chắc. Tôi thường sử dụng trình tạo mật khẩu trên trình duyệt tại toolcraft.app/vi/tools/security/password-generator cho mật khẩu server. Nó tạo entropy cục bộ, vì vậy không có dữ liệu nhạy cảm nào được gửi qua mạng. Khi quyền truy cập của bạn đã an sau, hãy mở cấu hình Nginx.

Bước 1: Triển khai HSTS

Để bật HSTS, hãy thêm dòng này vào block server của bạn. Hầu hết các trang web production sử dụng thời hạn 1 năm. Mở tệp cấu hình trang web của bạn (thường ở /etc/nginx/sites-available/) và thêm nội dung sau:

server {
    listen 443 ssl http2;
    server_name example.com;

    # HSTS (thời hạn 1 năm)
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

    # phần còn lại của cấu hình...
}

Tham số always là cực kỳ quan trọng. Nó đảm bảo header được gửi ngay cả trên các trang lỗi 404 hoặc 500. Cờ preload cho phép bạn gửi tên miền của mình vào danh sách preload HSTS của Google để đạt được mức độ bảo mật tối đa.

Bước 2: Chặn Clickjacking và Sniffing

Mặc dù CSP xử lý hầu hết các vấn đề này, X-Frame-Options cung cấp một mạng lưới an toàn cho các trình duyệt cũ hơn. Sử dụng hai dòng này để ngăn chặn việc nhúng khung hình (framing) và thay đổi MIME-type cưỡng bức:

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

Header nosniff ngăn trình duyệt cố gắng đoán định dạng tệp. Điều này ngăn kẻ tấn công ngụy trang một script độc hại dưới dạng một tệp hình ảnh vô hại.

Bước 3: Xây dựng Content Security Policy (CSP)

CSP có thể rất nghiêm ngặt, vì vậy hãy bắt đầu với một chính sách cho phép tên miền của chính bạn và các tài nguyên bên ngoài đáng tin cậy. Một điểm khởi đầu vững chắc cho một trang web hiện đại sẽ như thế này:

add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://scripts.trusted.com; object-src 'none'; frame-ancestors 'self';" always;
  • default-src 'self': Mặc định tin tưởng tên miền của chính bạn.
  • object-src 'none': Vô hiệu hóa các plugin cũ như Flash, vốn là các vectơ khai thác thường xuyên.
  • frame-ancestors 'self': Cách hiện đại để ngăn chặn Clickjacking trên tất cả các trình duyệt chính.

Bước 4: Hạn chế quyền truy cập phần cứng

Cuối cùng, hãy đóng quyền truy cập vào các cảm biến nhạy cảm. Sử dụng header Permissions-Policy để từ chối các tính năng bạn không sử dụng:

add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), interest-cohort=()" always;

Lưu ý phần interest-cohort=(). Điều này giúp trang web của bạn không tham gia vào việc theo dõi FLoC của Google, một lựa chọn phổ biến cho các nhà phát triển chú trọng đến quyền riêng tư.

Kiểm tra và xác minh

Đừng bao giờ reload Nginx mà không kiểm tra cú pháp trước. Một dấu chấm phẩy bị thiếu sẽ làm hỏng máy chủ web của bạn. Chạy lệnh sau:

sudo nginx -t

Nếu bài kiểm tra vượt qua, hãy reload dịch vụ để áp dụng các thay đổi:

sudo systemctl reload nginx

Xác minh các header đã hoạt động bằng curl. Tìm các dòng bảo mật mới của bạn trong phản hồi:

curl -I https://yourdomain.com

Chiến lược dài hạn: Bảo trì

Bảo mật là một quá trình, không phải là công việc làm một lần. Nếu bạn thêm một video YouTube nhúng hoặc một công cụ phân tích mới, CSP của bạn có thể sẽ chặn nó lúc đầu. Bạn sẽ cần cập nhật danh sách trắng của mình cho phù hợp. Tôi khuyên bạn nên kiểm tra log hàng tuần để xem các báo cáo vi phạm CSP.

Bằng cách triển khai các header này, bạn chuyển từ việc lưu trữ cơ bản sang bảo vệ chủ động. Những thay đổi này chỉ mất khoảng mười phút để triển khai. Tuy nhiên, chúng có thể cứu bạn khỏi cơn ác mộng về quan hệ công chúng và nợ kỹ thuật từ một cuộc tấn công injection dữ liệu thành công.

Share: