Headers Như Những Túi Dữ Liệu
Các framework ghi log HTTP coi các header của request như một túi các cặp key-value. API ghi log phơi bày toàn bộ túi. Các nhà vận hành bật ghi log header để debug: khi một request thất bại, các header kể lại câu chuyện. Không có danh sách từ chối tích hợp sẵn. Không có bộ lọc thông tin xác thực trong tài liệu. Toàn bộ header được ghi xuống đĩa.
Các header chứa thông tin xác thực trong một request điển hình:
- Authorization: Bearer eyJhbGciOiJIUzI1NiJ9... (JWT hoặc OAuth token)
- Cookie: session=abc123; auth=xyz789
- X-API-Key: sk-live-abc123...
- X-Auth-Token: ghp_abc123... (Mẫu token truy cập cá nhân GitHub)
Các giá trị này xác thực yêu cầu. Khi được ghi vào tệp nhật ký, chúng có thể xác thực bất kỳ yêu cầu nào.
Đường dẫn thông tin xác thực
Một thông tin xác thực được ghi vào tệp nhật ký không nằm yên một chỗ. Nó di chuyển:
1. Máy chủ web ghi vào /var/log/nginx/access.log
2. Tác nhân xoay vòng nhật ký (logrotate) sao chép sang /var/log/nginx/access.log.1
3. Tác nhân vận chuyển nhật ký (Fluentd, Filebeat, Logstash) đọc và gửi đến bộ tổng hợp
4. Bộ tổng hợp nhật ký (Elasticsearch, Splunk, Datadog) lập chỉ mục & lưu trữ
5. Giữ lại trong 30-90 ngày theo chính sách mặc định
Thông tin xác thực tồn tại đồng thời ở cả năm vị trí. Việc thu hồi token phiên không xóa thông tin xác thực khỏi bộ tổng hợp nhật ký. Nó vẫn có thể tìm kiếm, xuất & truy cập được bởi bất kỳ ai có quyền truy cập nhật ký trong toàn bộ khoảng thời gian lưu giữ.
Cửa sổ phơi nhiễm
Cửa sổ phơi nhiễm cho thông tin xác thực trong bộ nhớ: max(thời lượng phiên, tuổi thọ tiến trình). Phiên: vài giờ đến vài ngày. Tiến trình: vài giờ đến vài tuần.
Cửa sổ phơi nhiễm cho thông tin xác thực trong nhật ký: max(thời lượng phiên, thời gian lưu giữ nhật ký). Phiên: vài giờ đến vài ngày. Lưu giữ: 30-90 ngày.
Một thông tin xác thực bị đánh cắp từ bộ nhớ yêu cầu kẻ tấn công phải hiện diện trong cửa sổ phiên. Một thông tin xác thực bị đánh cắp từ nhật ký chỉ cần quyền truy cập vào bộ tổng hợp nhật ký, có sẵn theo cách hồi cứu, trong toàn bộ khoảng thời gian lưu giữ.
MOAD-0003 so với MOAD-0004
MOAD-0003 (Rò rỉ ngữ cảnh): một thông tin xác thực trong bộ nhớ bị rò rỉ sang trình xử lý yêu cầu sai. Chỉ có thể truy cập trong cửa sổ xử lý, thông qua pool luồng. Tạm thời.
MOAD-0004 (Bí mật được ghi log): một thông tin xác thực trên đĩa vẫn tồn tại qua quá trình xoay log, vận chuyển log và tổng hợp log. Có thể truy cập ngược dòng, bởi bất kỳ ai có quyền truy cập log, trong 30-90 ngày. Kiên trì.
Sự khác biệt về cấu trúc: tạm thời so với kiên trì. Bản sửa hoạt động ở một lớp khác.
Tạm thời so với Kiên trì
Sự phân biệt tạm thời/kiên trì xác định bề mặt rủi ro, lớp sửa chữa và các yêu cầu phản hồi sự cố.
Danh sách Từ chối Thông tin Xác thực tại Lớp Tuần tự hóa
Giải pháp: một danh sách từ chối thông tin xác thực tại lớp tuần tự hóa. Trước khi bất kỳ giá trị header nào đến đầu ra nhật ký, hãy kiểm tra tên header với danh sách từ chối. Thay thế giá trị bằng [REDACTED].
CREDENTIAL_HEADERS = {
'authorization',
'cookie',
'x-api-key',
'x-auth-token',
'x-csrf-token',
'proxy-authorization',
}
def sanitize_headers(headers: dict) -> dict:
return {
k: '[REDACTED]' if k.lower() in CREDENTIAL_HEADERS else v
for k, v in headers.items()
}
Danh sách từ chối (denylist) nên nằm ở lớp serialization, không phải ở lớp truy vấn log. Redaction ở lớp truy vấn log: áp dụng sau khi thông tin nhạy cảm đã được ghi xuống đĩa; giá trị gốc vẫn tồn tại, chỉ bị ẩn khi hiển thị. Redaction ở lớp serialization: thông tin nhạy cảm không bao giờ chạm đến đĩa. Giá trị gốc không bao giờ xuất hiện trong file log, log shipper hay log aggregator.
Kiểm thử Danh sách Từ chối
Ba mẫu kiểm thử:
- Positive: một request với Authorization: Bearer token123 tạo ra mục log chứa Authorization: [REDACTED]
- Tiêu cực: một yêu cầu với Content-Type: application/json tạo ra mục nhật ký với giá trị nguyên vẹn
- Không phân biệt chữ hoa chữ thường: AUTHORIZATION: Bearer token123 cũng tạo ra [REDACTED] (tên header HTTP không phân biệt chữ hoa chữ thường)
Danh sách chặn yêu cầu bảo trì: các mẫu header thông tin xác thực mới (ví dụ: header tùy chỉnh X-Service-Auth) cần được thêm rõ ràng. Bản sửa là mang tính cấu trúc nhưng không tự duy trì.
Áp dụng Danh sách chặn
Một nhóm cấu hình định dạng log truy cập Nginx để bao gồm tất cả các header yêu cầu nhằm gỡ lỗi sự cố production. Cấu hình:
log_format debug_format '$remote_addr - $request - $http_authorization - $http_cookie';
access_log /var/log/nginx/debug.log debug_format;
Họ giải quyết sự cố và dự định xóa cấu hình debug, nhưng thay đổi không được áp dụng lên production trước chu kỳ triển khai tiếp theo (7 ngày sau).