0

Web cache deception - đánh lừa bộ nhớ đệm web (phần 1)

I. Giới thiệu

Web cache deception là một dạng tấn công mới nhắm vào bộ nhớ đệm trong những năm gần đây. Nhắc tới lỗ hổng web cache deception, một số bạn có thể liên tưởng tới một dạng lỗ hổng chúng ta đã phân tích - web cache poisoning. Vậy thì chúng khác nhau như thế nào? Đầu tiên về tên gọi, poisoning là đầu độc, deception là sự đánh lừa. Hai dạng tấn công này khác nhau chủ yếu ở cách thực hiện, còn mục tiêu chung nhắm đến đều là bộ nhớ đệm web.

Với web cache poisoning, kẻ tấn công đầu độc bộ nhớ đệm của web server bằng cách lưu trữ các nội dung độc hại vào cache. Cụ thể, chúng sẽ gửi một yêu cầu HTTP được thiết kế đặc biệt với các tham số hoặc header thay đổi để nội dung độc hại được lưu vào bộ nhớ đệm. Khi các người dùng khác sử dụng chức năng dẫn đến yêu cầu cùng gói tin đó, bộ nhớ đệm trả về nội dung đã bị nhiễm độc, dẫn đến nạn nhân không chủ ý truy cập vào nội dung không mong muốn và bị tấn công XSS, đánh cắp thông tin, hoặc chuyển hướng truy cập. (Tham khảo thêm tại link).

image.png

Với web cache deception, mục tiêu của dạng tấn công này là đánh lừa hệ thống bộ nhớ đệm lưu trữ các tài nguyên nhạy cảm hoặc cá nhân. Kẻ tấn công sẽ cố gắng thêm các yếu tố không hợp lệ (ví dụ ?file=secret) vào gói tin, làm cho máy chủ web xử lý yêu cầu này một cách bình thường nhưng hệ thống cache lại lưu lại phiên bản chứa nội dung riêng tư đó. Các người dùng khác khi yêu cầu cùng gói tin có thể nhận được hoặc bị đánh cắp dữ liệu nhạy cảm tùy vào thời điểm yêu cầu.

So sánh điểm khác biệt qua bảng:

Đặc điểm Web Cache Poisoning Web Cache Deception
Mục tiêu Đầu độc cache với nội dung độc hại Đánh lừa cache lưu nội dung nhạy cảm
Cách thức Yêu cầu với header/param độc hại Thêm yếu tố giả mạo, không hợp lệ
Hậu quả Người dùng nhận nội dung độc hại Rò rỉ thông tin nhạy cảm của người dùng

II. Cache rules

Chúng ta đã được học về khái niệm cache keys và hiểu về cách thức hoạt động của hệ thống máy chủ cache dựa trên các cache keys. Trong bài viết này, chúng ta cần trang bị thêm kiến thức về cache rules - là nguyên nhân chính dẫn tới lỗ hổng web cache deception.

Cache rules là tập hợp các quy tắc, hướng dẫn xác định cách dữ liệu được lưu trữ, làm mới và quản lý trong bộ nhớ đệm (cache) của hệ thống. Việc thiết lập các quy tắc cache hợp lý có thể giúp cải thiện tốc độ tải trang web, giảm tải cho máy chủ, và tăng trải nghiệm người dùng. Một số thành phần cơ bản và quy tắc phổ biến trong việc thiết lập cache bao gồm:

1. Thời gian tồn tại của Cache (Cache Duration / TTL)

Time-to-Live (TTL) là thời gian một tài nguyên được giữ trong bộ nhớ đệm trước khi nó được làm mới. Thời gian này được cấu hình tùy thuộc vào loại nội dung.

  • Nội dung tĩnh (static) như hình ảnh, CSS, JavaScript thường có TTL dài vì chúng ít thay đổi.
  • Nội dung động (dynamic), như dữ liệu người dùng hoặc các trang có nhiều cập nhật, thường có TTL ngắn hơn hoặc không được lưu trong cache.

Ví dụ: Một hình ảnh sản phẩm có thể có TTL là 30 ngày, trong khi một trang giỏ hàng nên có TTL là 0.

2. Cache-Control Header

Cache-Control là header HTTP phổ biến để chỉ định các quy tắc cache cho trình duyệt và bộ nhớ đệm proxy. Các thuộc tính thường dùng của Cache-Control bao gồm:

  • public: Cho phép nội dung được lưu cache bởi bất kỳ thiết bị trung gian nào, như CDN hoặc proxy.
  • private: Chỉ cho phép cache ở thiết bị của người dùng, không phải ở các bộ nhớ đệm công cộng.
  • no-cache: Yêu cầu tải lại tài nguyên từ server mỗi khi có yêu cầu (không lưu đệm nội dung).
  • max-age: Định nghĩa TTL bằng số giây mà tài nguyên có thể được lưu trữ trong cache.

Ví dụ cấu hình cho hình ảnh, CSS, và JavaScript tĩnh trong nginx:

location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
    expires 30d;  # Lưu trữ trong 30 ngày
    add_header Cache-Control "public, max-age=2592000";  # max-age tính bằng giây
}

Ví dụ cấu hình cho nội dung HTML động cần tải mới mỗi lần truy cập:

location /dynamic-content/ {
    add_header Cache-Control "no-store, must-revalidate";
}

3. Etag và Last-Modified Header

Etag (Entity Tag)Last-Modified là các header được dùng để kiểm tra xem nội dung đã được thay đổi hay chưa. Thay vì lưu nội dung mới hoàn toàn, hệ thống kiểm tra thông qua giá trị Etag hoặc Last-Modified và chỉ cập nhật nội dung khi có thay đổi.

Ví dụ: Khi người dùng tải lại trang, nếu nội dung chưa thay đổi, trình duyệt chỉ yêu cầu các tài nguyên được đánh dấu bằng Etag cũ, giảm băng thông.

Ví dụ cấu hình ETag trong Apache:

<IfModule mod_headers.c>
    Header set ETag "%{FILEETAG}e"  # Tạo ETag dựa trên thuộc tính tệp
</IfModule>

4. Content-Based Caching Rules (Cache dựa trên loại nội dung)

Một số tài nguyên có thể được lưu trong cache lâu hơn, trong khi một số khác không được cache hoặc có thời gian ngắn. Ví dụ:

  • Static Assets: CSS, JavaScript, hình ảnh – thường có thời gian cache dài (có thể lên đến 1 năm).
  • Dynamic Content: Trang cá nhân, giỏ hàng – thường không cache hoặc có TTL rất ngắn.

5. Vary Header

Vary header quyết định cách nội dung được lưu trong cache dựa trên các yếu tố khác nhau, chẳng hạn như Vary: User-Agent, Vary: Accept-Encoding. Có nghĩa là tài nguyên sẽ được lưu cache theo các phiên bản khác nhau dựa trên thiết bị, ngôn ngữ, hoặc các yếu tố khác, tránh việc một phiên bản nội dung được sử dụng không đúng ngữ cảnh.

Ví dụ cấu hình Vary cho ngôn ngữ và nén trong nginx:

location / {
    add_header Vary "Accept-Encoding, Accept-Language";  # Cache dựa trên ngôn ngữ và kiểu nén
}

Ví dụ cấu hình Vary cho thiết bị trong Apache:

<IfModule mod_headers.c>
    Header append Vary User-Agent  # Cache khác nhau theo loại thiết bị
</IfModule>

6. Cache Busting

Cache Busting là kỹ thuật làm mới bộ nhớ đệm của các tệp tĩnh mà không cần thay đổi URL của tài nguyên đó. Thường được thực hiện bằng cách thêm tham số phiên bản hoặc mã băm vào cuối URL, như style.css?v=1.0.1, để buộc tải lại các tài nguyên được thay đổi khi có bản cập nhật.

Ví dụ thêm tham số phiên bản cho tệp CSS:

<link rel="stylesheet" href="styles/main.css?v=2.0.1">

7. Client-Side và Server-Side Caching

Client-Side Caching: Các quy tắc cache được cấu hình để dữ liệu có thể lưu trữ ngay trên trình duyệt của người dùng, cho phép tải lại trang nhanh hơn khi người dùng quay lại.

Server-Side Caching: Các hệ thống proxy hoặc CDN (Content Delivery Network) lưu các bản sao của nội dung trên máy chủ gần người dùng, giảm độ trễ và tải trọng trên máy chủ chính.

8. Negative Caching (Cache tiêu cực)

Đôi khi, nội dung không tồn tại hoặc bị lỗi (như lỗi 404) được coi là negative, có thể được lưu cache trong một khoảng thời gian ngắn để tránh yêu cầu lặp lại liên tục lên server, giảm tải hệ thống.

Ví dụ lưu trữ tạm thời các lỗi 404 trong nginx:

error_page 404 /404.html;
location = /404.html {
    add_header Cache-Control "public, max-age=300";  # Lưu trạng thái 404 trong 5 phút
}

Tài liệu tham khảo


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí