Vượt Mặt CSP Nonce: Kỹ Thuật Khai Thác XSS Lợi Dụng Cache Trình Duyệt

Trong một khám phá đột phá thách thức mức độ an toàn được nhận định của Content Security Policy (CSP) dựa trên nonce, các nhà nghiên cứu bảo mật đã trình bày một phương pháp thực tế để bỏ qua các biện pháp bảo vệ này. Kỹ thuật này kết hợp tiêm HTML, rò rỉ nonce dựa trên CSS, và thao túng bộ nhớ cache của trình duyệt.

Nghiên cứu tập trung vào một ứng dụng web tối giản, có chứa một biểu mẫu đăng nhập và một trang điều khiển (dashboard). Trang điều khiển này được bảo vệ bởi một CSP dựa trên nonce, một cơ chế được coi là biện pháp phòng thủ mạnh mẽ chống lại các cuộc tấn công Cross-Site Scripting (XSS).

Theo nguyên tắc hoạt động, mỗi lần tải trang, một nonce duy nhất sẽ được tạo ra và nhúng vào cả chính sách CSP cũng như thẻ <script>. Điều này về mặt lý thuyết chỉ cho phép các script được tin cậy thực thi.

Lỗ hổng cốt lõi và Vector ban đầu

Mặc dù được bảo vệ bởi CSP, ứng dụng web trong nghiên cứu chứa một lỗ hổng tinh vi: dữ liệu đầu vào của người dùng được chèn vào trang bằng cách sử dụng thuộc tính .innerHTML mà không qua quá trình làm sạch (sanitization) đúng cách. Mặc dù về lý thuyết CSP sẽ chặn bất kỳ script nào được tiêm vào, các nhà nghiên cứu đã tìm ra một cách để vượt qua cơ chế bảo vệ này.

Quy trình khai thác chi tiết

Quy trình tấn công được chia thành hai bước chính, bao gồm việc thu thập giá trị nonce và sau đó tận dụng bộ nhớ cache của trình duyệt để thực thi payload độc hại.

Bước 1: Rò rỉ Nonce thông qua Kỹ thuật Tiêm CSS

Trở ngại đầu tiên là làm thế nào để lấy được giá trị nonce, vốn là yêu cầu bắt buộc để bất kỳ script nào được tiêm vào có thể thực thi. Các nhà nghiên cứu đã khai thác một điểm yếu: chính sách CSP của ứng dụng không hạn chế các thẻ <style> hoặc các biểu định kiểu ngoài (external stylesheets).

Bằng cách tiêm các bộ chọn CSS được tạo tác cẩn thận, họ có thể làm rò rỉ nonce từ thẻ <meta> của trang, nơi chứa chính sách CSP. Kỹ thuật này, lấy cảm hứng từ các thử thách CTF (Capture The Flag) trước đây, liên quan đến việc sử dụng các bộ chọn thuộc tính (attribute selectors)yêu cầu ảnh nền (background image requests). Cụ thể, các bộ chọn CSS có thể được thiết kế để khớp với các ký tự cụ thể trong giá trị nonce (ví dụ: meta[content*="nonce-a"]). Khi một phần của nonce khớp, một yêu cầu ảnh nền đến một URL do kẻ tấn công kiểm soát sẽ được kích hoạt, mang theo thông tin về ký tự khớp đó. Quá trình này được lặp lại, cho phép kẻ tấn công làm rò rỉ nonce thành các đoạn nhỏ, sau đó được tập hợp lại ở phía máy chủ của kẻ tấn công.

Bước 2: Khai thác Bộ nhớ Cache của Trình duyệt (bfcache và Disk Cache)

Khi đã có được giá trị nonce, thử thách tiếp theo là tiêm một payload sẽ được thực thi với nonce chính xác. Tại đây, các nhà nghiên cứu đã tận dụng các cơ chế bộ nhớ cache của trình duyệt—đặc biệt là back/forward cache (bfcache)disk cache.

bfcache là một tính năng trình duyệt lưu trữ toàn bộ trạng thái của một trang khi người dùng điều hướng đi chỗ khác, cho phép quay lại trang đó ngay lập tức mà không cần tải lại hoàn toàn. Disk cache là nơi trình duyệt lưu trữ các tài nguyên web tĩnh (như HTML, CSS, JavaScript, hình ảnh) để tải lại nhanh hơn trong các lần truy cập sau.

Bằng cách thao túng lịch sử điều hướng và khóa bộ nhớ cache (sử dụng các tham số truy vấn trong URL), các nhà nghiên cứu đã buộc trình duyệt phục vụ một phiên bản cũ của trang điều khiển (chứa nonce đã biết) từ disk cache. Đồng thời, họ tiến hành cập nhật dữ liệu hồ sơ người dùng với một payload XSS mới thông qua một cuộc tấn công Cross-Site Request Forgery (CSRF). Cuộc tấn công CSRF này lợi dụng phiên đăng nhập của người dùng để thực hiện hành động trên web ứng dụng mà người dùng không hay biết.

Sự tách biệt giữa HTML (với nonce cũ lấy từ cache) và dữ liệu động (với payload XSS mới được cập nhật qua CSRF) đã cho phép script được tiêm vào thực thi thành công. Điều này xảy ra do script được tiêm vào được xử lý trong ngữ cảnh của trang được tải từ cache (với nonce hợp lệ), trong khi dữ liệu độc hại được đưa vào thông qua một luồng riêng biệt. Sự kết hợp này đã phá vỡ cơ chế bảo vệ của CSP dựa trên nonce.

Hàm ý trong thế giới thực và Bài học

Cuộc tấn công này chứng minh rằng ngay cả các CSP dựa trên nonce được cấu hình tốt cũng có thể bị đánh bại nếu:

  • Các giá trị nonce có thể bị rò rỉ ra ngoài môi trường không được kiểm soát.
  • Dữ liệu đầu vào của người dùng không được làm sạch đầy đủ trước khi được chèn vào DOM.
  • Các hành vi bộ nhớ cache của trình duyệt không được hiểu rõ và tính đến trong mô hình mối đe dọa.

Nghiên cứu nhấn mạnh tầm quan trọng của việc áp dụng bảo mật web một cách toàn diện. CSP nonces là một công cụ mạnh mẽ, nhưng chúng không phải là “viên đạn bạc” giải quyết mọi vấn đề. Các nhà phát triển phải đảm bảo rằng:

  • Nonces không thể bị rò rỉ thông qua các kênh không mong muốn.
  • Mọi dữ liệu đầu vào của người dùng phải được làm sạch đúng cách, đặc biệt khi được chèn vào HTML.
  • Hành vi bộ nhớ cache của trình duyệt phải được hiểu rõ và được tính toán trong các mô hình mối đe dọa của ứng dụng để ngăn chặn việc lợi dụng các phiên bản trang cũ.

Phát hiện này là một lời nhắc nhở quan trọng: bảo mật chỉ mạnh bằng liên kết yếu nhất của nó. Kẻ tấn công sẽ tiếp tục tìm ra những cách sáng tạo để khai thác các tương tác bị bỏ qua giữa các công nghệ web.