Web Cache Deception: Khi máy chủ bị đánh lừa chỉ bằng một dấu chấm phẩy (;)
Ý kiến
0
Chưa có ý kiến nào. Hãy là người đầu tiên chia sẻ!
Chưa có ý kiến nào. Hãy là người đầu tiên chia sẻ!
Bạn đã bao giờ tưởng tượng toàn bộ thông tin thẻ tín dụng, lịch sử mua hàng, hay token đăng nhập của mình lại bị phơi bày ra internet (public) chỉ vì một sai sót nhỏ trong cấu hình máy chủ? Đó không phải là kịch bản trong phim, mà là thực tế của lỗ hổng WEB CACHE DECEPTION (WCD).
Trong bài viết này mình sẽ chia sẻ lại hành trình tự build một bài Lab nội bộ và dùng công cụ Burp Suite để khai thác thành công lỗ hổng WCD thông qua kỹ thuật “Delimiter Discrepancies” (Sai lệch dấu phân cách).
Về cơ bản, WCD là một cuộc tấn công “mượn dao giết người”. Trong đó:
Kẻ tấn công lừa nạn nhân truy cập vào một URL độc hại (nhưng chứa thông tin nhạy cảm của nạn nhận).
Bộ nhớ đệm (Cache Server- ví dụ: Nginx, Cloudflare) đứng giữa hiểu lầm URL này là một file tĩnh (như .css, .png) nên đã lưu lại (Cache) kết quả.
Kẻ tấn công sau đó chỉ cần truy cập vào đúng URL đó để lấy toàn bộ dữ liệu nhạy cảm của nạn nhân từ Cache.
Tại sao Cache lại hiểu lầm? Đó là do sự bất đồng bộ giữa Cache Server và Origin Server (Máy chủ gốc -PHP/java).
Khi có một request đến - vd : /api.php/ORD-12345;test.css
Máy chủ PHP sẽ cắt bỏ toàn bộ chuỗi từ đầu ; trở đi. Nó hiểu rằng client đang muốn xem hóa đơn ORD-12345 và trả về một file JSON nhạy cảm.
Máy chủ Cache, ngược lại, không xem ; là dấu phân cách. Nó đọc toàn bộ URL, thấy có đuôi .css ở cuối cùng. Theo rule cấu hình, nó mặc định đây là file giao diện (tĩnh) và quyết định lưu file JSON nhạy cảm đó vào bộ nhớ dùng chung.
Để hiểu rõ tận gốc rễ, mình đã tự viết một trang web mua sắm nhỏ bằng PHP. Dưới đây là đoạn code “tội lỗi” gây ra lỗ hổng WCD:
PHP
// Trích xuất phần ID phía sau "api.php/"
$raw_id = explode('api.php/', $path)[1];
// [!!! LỖ HỔNG DELIMITER DISCREPANCY NẰM Ở ĐÂY !!!]
// Lập trình viên cố tình dùng hàm explode để cắt bỏ chuỗi sau dấu ';'
$clean_id = explode(';', $raw_id)[0];
$clean_id = explode('.', $clean_id)[0];
// Xử lý logic và trả về dữ liệu nhạy cảm của người dùng
$order_data = [
"order_id" => $clean_id,
"credit_card" => "****-****-****-9999", // Dữ liệu nhạy cảm
"secret_token" => "TKN-XYZ-8888"
];
echo json_encode($order_data);
#Ghi chú: Đoạn code trên trông có vẻ vô hại vì nó giúp hệ thống “linh hoạt” hơn khi xử lý URL bị lỗi, nhưng lại vô tình mở toang cánh cửa cho WCD.
Để chứng minh lỗ hổng, mình đã bật trình duyệt tính hợp của Burp Suite và thực hiện 3 bước:
Bước 1 (Đóng Vai nạn nhân): Đăng nhập vào hệ thống (lấy Cookie hợp lệ) và tiến hành gọi API hóa đơn với một Payload giả mạo phần mở rộng:
👉 GET /api.php/ORD-12345;test.css HTTP/1.1
Bước 2 (Kiểm tra phản hồi): Máy chủ PHP trả về mã chứa dữ liệu 200 OK JSON nhạy cảm. Header của Nginx Cache trả về X-Cache-Status: MISS lần đầu tiên gọi nên Cache tiến hành ghi nhớ).
Bước 3(Đóng vai kể tấn công): Mở tap Repeater trong Burp Suite, XÓA TOÀN BỘ COOKIE (để giả lập một ngời lạ không có tài khoản) và gửi lại đúng request trên.
👉 Kết quả: Mình vẫn nhận được toàn bộ JSON chứa số thẻ tín dụng! Header lúc này trả về X-Cache-Status: HIT. Cache đã "phản bội" nạn nhân và giao nộp dữ liệu cho hacker.
Trải nghiệm tự build, tự phá hệ thống giúp mình rút ra những nguyên tắc vàng trong bảo mật:
Đừng bao giờ tin tưởng URL: Các Backend framework không nên tự động cắt gọt, làm sạch các dấu phân cách lạ (như ;, %00, %0A) để cố gắng "đoán" ý người dùng. Nếu URL sai chuẩn API, hãy thẳng tay trả về 404 Not Found hoặc 400 Bad Request.
Cấu hình Cache chặt chẽ: Chỉ nên cache các tài nguyên tĩnh thực sự dựa trên thư mục cụ thể (ví dụ: chỉ cache tài nguyên nằm trong thư mục /assets/ hoặc /static/), thay vì chỉ dựa vào phần mở rộng (extension) như .css hay .js.
Set Header Cache-Control: Đối với các API trả về dữ liệu động nhạy cảm của người dùng, máy chủ gốc (Origin) bắt buộc phải luôn luôn đính kèm header Cache-Control: private, no-store để cấm Cache Server lưu trữ dưới mọi hình thức.
Web Cache Deception là một minh chứng rõ ràng cho việc: Lỗ hổng không phải lúc nào cũng đến từ những dòng code phức tạp, mà có thể đến từ sự "lệch pha" giữa các hệ thống hoạt động cùng nhau (Cache và Origin).
Nếu các bạn muốn tự tay trải nghiệm lỗ hổng này trên các môi trường thực tế hơn, mình cực kỳ khuyến nghị các bài Lab về Web Cache Deception trên PortSwigger Web Security Academy.