IV. Static directory cache rules attack
1. Cache rules
Đây là các cache rules dành cho các tệp tin tĩnh nằm trong một số thư mục (thường là public) như /static
, /assets
, /scripts
, /images
, ... Khi người dùng truy cập đến các tệp tin này, thường trong URL sẽ chứa các từ khóa này.
Ví dụ cache rules tại server cache:
cache_rules: # Cache static assets only in the /static directory with specific file extensions - condition: url: prefix: "/static" extension: matches: [".css", ".js", ".png", ".jpg", ".jpeg", ".gif", ".ico", ".svg"] action: cache: true ttl: 86400 # Cache static assets for 24 hours
Như vậy, khi người dùng truy cập tới các tệp tin tĩnh có phần mở rộng trong whitelist và nằm trong thư mục /static
sẽ kích hoạt cache rule này, chẳng hạn http://example.com/static/test.png
2. Khai thác thông qua kỹ thuật lùi thư mục
Xem xét route xử lý trả về các tệp tin trong thư mục /static
tại một server Express.js:
const express = require('express');
const path = require('path'); // ... app.use('/static', express.static(path.join(__dirname, 'static')));
Việc xử dụng path.join(__dirname, 'static')
sẽ cho phép người dùng "lùi" thư mục trong chính URL. Ví dụ, khi người dùng gửi yêu cầu truy cập tới /static/..%2fprofile?abc.ico
, server thực hiện URL decode chuỗi này và hiểu rằng người dùng đang muốn truy cập tới /profile?abc.ico
.
Tuy nhiên server cache có thể không "hiểu" giống server chính, chỉ dựa vào các cache rules và nhận thấy rằng request thỏa mãn truy cập file kết thúc bằng .ico
nằm trong thư mục /static
nên cache rules được kích hoạt, dẫn đến nội dung tại /profile
của người dùng bị lưu vào server cache.
Để bạn đọc hiểu chi tiết hơn về dạng tấn công này, chúng ta cùng xem xét và phân tích các kết quả phản hồi khác nhau trong bài lab Exploiting origin server normalization for web cache deception
Mục đích bài lab là đánh lừa server cache lại nội dung hồ sơ chứa API key của nạn nhân:
Quan sát lịch sử request đi qua proxy nhận thấy tệp tin labs.css
nằm trong thư mục /resources/css
thỏa mãn cache rules:
Phản hồi của server chính
Xét request xem hồ sơ cá nhân tại API /my-account
, sử dụng kỹ thuật lùi thư mục ..%2f
xem xét cách server chính xử lý API /my-account/..%2fresources/css/labs.css
Response trả về nội dung tại /resources/css/labs.css
, chứng tỏ server chính xử lý ..%2f
bằng cách URL decode và lùi thư mục thành công.
Phản hồi của server cache
Quan sát lại response tại /my-account/..%2fresources/css/labs.css
nhận thấy cache rules không được kích hoạt. Bởi vì server đang hiểu request này gọi đến tệp tin nằm trong thư mục /my-account
. Sửa lại payload để đánh lừa server cache chúng ta đang yêu cầu tới tệp tin nằm trong thư mục /resources
, payload mới /resources/my-account/..%2fcss/labs.css
, kết quả kích hoạt cache rules thành công:
Cache lại nội dung nhạy cảm
Sau khi hiểu rõ cách hoạt động của server chính và server cache, công việc cuối cùng của chúng ta là xây dựng payload nhằm đánh lừa hai server cache lại nội dung tại /my-account
.
Để server cache kích hoạt cache rules, hai yếu tố sau cần thỏa mãn đồng thời:
- API cần bắt đầu bằng
/resources
- API cần kết thúc bằng
.css
Để server chính trả về nội dung tại /my-account
, cần thỏa mãn kết quả thư mục được lùi tại chính xác /my-account
Đến đây, ý tưởng tự nhiên cho thấy chúng ta cần tìm kiếm một ký tự với mục đích "loại bỏ" phần hậu tố .css
khỏi server chính. Thực hiện tương tự cách brute force trong phần trước, kết quả có thể sử dụng ký tự ?
. Payload cuối cùng như sau:
/resources/..%2fmy-account?/..%2f.css
Đến đây thì phần công việc còn lại là gửi URL này tới victim thôi!
Đôi khi, chúng ta cũng cần thực hiện URL encode cả ký tự .
, tùy thuộc vào cách chúng được xử lý tại server. Một bài lab khác dành cho bạn đọc tự khám phá: Exploiting cache server normalization for web cache deception.
3. Ngăn chặn static directory cache rules attack
Phương thức tấn công lỗ hổng web cache deception bằng cách kết hợp kỹ thuật lùi thư mục nhắm vào cách xử lý khác biệt của server chính và server cache đối với các API attacker yêu cầu. Chúng ta xem xét một số biện pháp ngăn chặn.
Đầu tiên, cần thiết lập kiểm soát URL một cách nghiêm ngặt. Trước khi gửi URL đến server cache hoặc xử lý, cần đảm bảo các URL đã được chuẩn hóa để loại bỏ các chuỗi lùi thư mục ..
hay các ký tự %2e/%2f
được mã hóa. Hoặc từ chối trực tiếp các yêu cầu chứa ký tự mã hóa liên quan đến dấu chấm .
hoặc dấu gạch chéo /
, đặc biệt là %2e
và %2f
khi xử lý URL nếu cần thiết.
Ví dụ middleware thực hiện chuẩn hóa URL và kiểm tra path traversal:
app.use((req, res, next) => { const normalizedPath = path.normalize(req.url); if (normalizedPath.includes('..') || req.url.includes('%2e') || req.url.includes('%2f')) { return res.status(400).send('Invalid request'); } next();
});
Đối với cache rules, cần cấu hình một cách thận trọng. Nên giới hạn các thư mục cache bằng cách đảm bảo chỉ kích hoạt cache cho các thư mục chứa tệp tĩnh như /static
, /assets
, và không cache cho các thư mục chứa dữ liệu nhạy cảm như /profile
hay /my-account
. Kết hợp cài đặt các header Cache-Control cho từng endpoint. Đối với các endpoint nhạy cảm hoặc động, dùng Cache-Control: no-store
để ngăn cache server lưu lại dữ liệu. Ví dụ:
cache_rules: # Chỉ cache các tệp trong thư mục /static và có các phần mở rộng xác định - condition: url: prefix: "/static" extension: matches: [".css", ".js", ".png", ".jpg", ".jpeg", ".gif", ".ico", ".svg"] action: cache: true ttl: 86400 # Cache các tệp tĩnh trong 24 giờ # Từ chối cache cho các URL khác hoặc không có phần mở rộng phù hợp - condition: url: prefix: "/" action: cache: false
Cuối cùng, có thể theo dõi và phát hiện bất thường bằng cách kiểm tra log để phát hiện các request bất thường hoặc các yêu cầu chứa các kỹ thuật mã hóa hay lùi thư mục. Thiết lập hệ thống báo cáo hoặc chặn tự động các request này. Sử dụng công cụ quét bảo mật để phát hiện các lỗi path traversal, cache poisoning và các lỗ hổng bảo mật liên quan.