Tăng Cường Laravel: Các HTTP Security Header Thiết Yếu

· 4 min read

Bảo mật một ứng dụng web không chỉ là validate input và escape output (mặc dù những điều đó rất quan trọng). Đó còn là việc nói cho trình duyệt cách hành xử khi tải trang của bạn.

HTTP Security Header là các chỉ dẫn được gửi bởi server đến trình duyệt. Chúng có thể ngăn chặn Cross-Site Scripting (XSS), Clickjacking, và các tấn công khác.

Với blog Markdown có thể render HTML do người dùng cung cấp (hiếm, nhưng có thể) hoặc tải external script, đây là điều thiết yếu.

Cách Thêm Header trong Laravel

Nơi tốt nhất để thêm global header là trong Middleware.

Tạo middleware mới:

php artisan make:middleware SecurityHeaders

Trong app/Http/Middleware/SecurityHeaders.php:

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class SecurityHeaders
{
    public function handle(Request $request, Closure $next): Response
    {
        $response = $next($request);

        $response->headers->set('X-Content-Type-Options', 'nosniff');
        $response->headers->set('X-Frame-Options', 'DENY');
        $response->headers->set('X-XSS-Protection', '1; mode=block');
        $response->headers->set('Referrer-Policy', 'strict-origin-when-cross-origin');
        $response->headers->set('Content-Security-Policy', "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self';");

        return $response;
    }
}

Đừng quên đăng ký nó trong bootstrap/app.php (cho Laravel 11) hoặc app/Http/Kernel.php (phiên bản cũ hơn).

Phân Tích Các Header

1. X-Content-Type-Options: nosniff

Ngăn trình duyệt "đánh hơi" content type. Nếu bạn phục vụ file dưới dạng text/plain, trình duyệt sẽ không cố thực thi nó như JavaScript, ngăn chặn tấn công nhầm lẫn MIME type.

2. X-Frame-Options: DENY

Điều này ngăn trang của bạn bị tải trong <iframe> trên trang khác. Điều này tiêu diệt các nỗ lực Clickjacking khi kẻ tấn công phủ trang của bạn bằng nút vô hình.

3. Strict-Transport-Security (HSTS)

(Không bao gồm trong code ở trên vì nó yêu cầu HTTPS). Nếu bạn phục vụ trang qua HTTPS (bạn nên làm vậy), HSTS nói với trình duyệt: "Không bao giờ tải trang này qua HTTP nữa, tự động nâng cấp lên HTTPS."

Trong production (ví dụ: Nginx config), hoặc trong middleware nếu thực thi nghiêm ngặt:

if (app()->environment('production')) {
    $response->headers->set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
}

4. Content-Security-Policy (CSP)

Big boss của security header. Nó định nghĩa chính xác nơi resource (JS, CSS, Image) có thể được tải từ đâu.

Ví dụ được cung cấp: default-src 'self' -> Chỉ tải asset từ domain của tôi.

Nếu bạn sử dụng Google Analytics hoặc Font, bạn phải whitelist chúng: script-src 'self' https://www.google-analytics.com

Cảnh báo: Triển khai CSP nghiêm ngặt đại diện cho "rủi ro hỏng hóc" cao. Nếu bạn chặn inline style hoặc script, một phần frontend stack của bạn (như Alpine.js hoặc Tailwind) có thể cần cấu hình cụ thể (như nonce hoặc hash).

Middleware vs Web Server Config

Bạn nên làm điều này trong PHP (Laravel) hay Nginx/Apache?

  • Nginx: Nhanh hơn. Sử dụng cho static asset và quy tắc chung.
  • Laravel Middleware: Linh hoạt hơn. Sử dụng nếu bạn cần logic có điều kiện (ví dụ: nới lỏng CSP cho route admin cụ thể).

Với blog đơn giản, Middleware là đủ và dễ quản lý version control cùng với code của bạn.

Kiểm Tra

Sử dụng securityheaders.com để quét trang của bạn. Hãy nhắm đến rating A+. Đó là huy hiệu danh dự cho bất kỳ blog developer nào.

Bình luận