Mô hình phòng thủ chiều sâu (defense-in-depth) của hạ tầng container đặt cược vào hai lớp ranh giới cốt lõi: kiểm soát ủy quyền tại daemon quản lý (Docker/Moby) và cô lập bộ nhớ tại nhân hệ điều hành (Linux Kernel). Hai lỗ hổng nghiêm trọng công bố đầu năm 2026 — Moby/Docker Engine CVE-2026-34040 và Linux Kernel CVE-2026-31431 (tên định danh là Copy Fail) — cho thấy ranh giới an toàn sụp đổ nhanh thế nào khi plugin trung gian rơi vào trạng thái "fail-open" và cơ chế tối ưu zero-copy ở tầng nhân làm lộ quyền ghi vào Page Cache.
Khi vận hành hạ tầng, chúng ta thường mặc định dữ liệu mà plugin bảo mật kiểm tra chính là dữ liệu daemon sẽ thực thi, và một file mở ở chế độ chỉ đọc (read-only) không thể làm thay đổi bộ nhớ dùng chung của máy chủ. Cả hai giả định này đều bị phá vỡ. Mổ xẻ căn nguyên kiến trúc của chúng giúp chúng ta thiết lập ranh giới cô lập đa tầng vững chắc hơn, thay vì chỉ bị động chờ bản vá.
CVE-2026-34040: Khi Middleware Ủy Quyền Rơi Vào Trạng Thái Fail-Open
Trong môi trường đa người dùng hoặc CI/CD dùng chung, các kỹ sư nền tảng thường dùng Docker Authorization (AuthZ) plugin (như OPA, Casbin) để kiểm soát mọi lệnh gọi tới Docker API. Các plugin này chặn từng HTTP request để từ chối các cấu hình nguy hiểm như cờ --privileged hay bind mount ổ cứng vật lý của host.
Công bố vào cuối tháng 3/2026 (điểm CVSS 8.8), CVE-2026-34040 phơi bày lỗi bất đối xứng dữ liệu trên mọi phiên bản Moby và Docker Engine trước 29.3.1 (cùng Docker Desktop trước 4.66.1). Đây là hệ quả từ việc bản vá lỗi CVE-2024-41110 trước đó chỉ mới xử lý trường hợp HTTP request body có độ dài bằng 0.
Căn nguyên nằm ở logic xử lý stream: khi Docker API nhận một HTTP payload có kích thước vượt ngưỡng phân bổ bộ đệm mặc định (lớn hơn 1 MB), daemon tự động loại bỏ (drop) phần thân khi chuyển tiếp yêu cầu đến AuthZ plugin.
Hệ quả là điểm quyết định chính sách (PDP - AuthZ plugin) chỉ nhận được Header và URI cùng phần body rỗng. Không thấy cấu hình vi phạm trong payload rỗng, plugin trả về kết quả phê duyệt (Allow). Trong khi đó, điểm thực thi chính sách (PEP - tiến trình Docker daemon) vẫn giữ nguyên và thực thi trọn vẹn request body ban đầu. Bất kỳ thiết kế middleware nào cắt bớt dữ liệu khi kiểm duyệt nhưng lại truyền toàn bộ dữ liệu gốc xuống tầng thực thi đều tạo ra lỗ hổng vượt rào kiến trúc.
CVE-2026-31431: Copy Fail Và Lỗi Ghi Đè Bộ Nhớ Đệm Page Cache

Ngay cả khi tầng kiểm soát API chặt chẽ, mọi container trên cùng một node vẫn chia sẻ chung nhân Linux và vùng nhớ Page Cache. Công bố vào tháng 4/2026, CVE-2026-31431 (điểm CVSS 7.8, tên gọi "Copy Fail") chỉ ra lỗi logic tồn tại từ năm 2017 (commit 72548b093ee3) trong module mật mã không gian người dùng crypto/algif_aead.c (AF_ALG socket).
Để tối ưu hiệu năng khi mã hóa xác thực AEAD, commit này cho phép xử lý dữ liệu trực tiếp tại chỗ (in-place operation). Lỗi cô lập xảy ra khi tiến trình kết hợp socket AF_ALG với lời gọi hệ thống splice(). Khi dùng splice() truyền dữ liệu từ một file chỉ đọc vào socket, kernel không sao chép byte mà đưa thẳng con trỏ tham chiếu các trang nhớ Page Cache của file đó vào danh sách phân tán nguồn.
Do algif_aead xử lý tại chỗ, các trang Page Cache chỉ đọc này bị đưa thẳng vào danh sách phân tán bộ nhớ đích có quyền ghi (writable destination scatterlist). Khi hàm recvmsg() hoàn tất quá trình mật mã, dữ liệu kết quả được ghi đè trực tiếp lên các trang Page Cache trong RAM.
Thao tác này vượt qua hoàn toàn bước kiểm tra quyền tập tin (DAC/MAC) vì diễn ra ở tầng cache nội bộ. Đồng thời, trang nhớ không phát sinh cờ dirty để ghi xuống đĩa, khiến các công cụ kiểm tra toàn vẹn tệp định kỳ không phát hiện được dấu vết, trong khi máy chủ vật lý và các container khác thực thi mã nhị phân đã bị biến đổi trong bộ nhớ.
So Sánh Kiến Trúc: Ranh Giới Daemon Và Ranh Giới Kernel

Đặt hai lỗ hổng cạnh nhau, ta thấy rõ cách sự lệch pha dữ liệu và chia sẻ bộ nhớ phá hủy tính cô lập:
| Tiêu chí kỹ thuật | Tầng Docker AuthZ (CVE-2026-34040) | Tầng Cô Lập Kernel (CVE-2026-31431) |
|---|---|---|
| Vị trí ranh giới | Userspace Daemon (Moby API Middleware) | Kernel Subsystem (algif_aead / Page Cache) |
| Mô hình lỗi | Cắt bỏ body > 1 MB & xử lý kiểu fail-open | Chia sẻ zero-copy làm lộ quyền ghi vào trang chỉ đọc |
| Vùng đệm tác động | Luồng HTTP Request Body Stream | In-memory Page Cache (scatterlist buffers) |
| Hệ quả vi phạm | Vượt qua chính sách kiểm soát API tạo container | Ghi đè bộ nhớ chỉ đọc xuyên ranh giới container |
| Giải pháp gốc | Lên bản 29.3.1; đồng bộ toàn vẹn body stream | Hủy cơ chế in-place AEAD; chặn AF_ALG bằng Seccomp |
Kỹ Thuật Phòng Thủ Và Khắc Phục Thực Chiến
Cập nhật bản vá là bắt buộc, nhưng kiến trúc phòng thủ chiều sâu đòi hỏi phải đóng các bề mặt tấn công không cần thiết.
1. Khóa Bề Mặt Tấn Công Mật Mã Kernel Bằng Seccomp
Bản cập nhật Linux kernel chính thức khắc phục CVE-2026-31431 bằng cách đưa crypto/algif_aead.c về cơ chế xử lý tách biệt (out-of-place). Nếu chưa thể khởi động lại cụm máy chủ ngay, bạn có thể chặn nạp module algif_aead trên host:
echo "install algif_aead /bin/false" | sudo tee /etc/modprobe.d/disable-algif-aead.conf
sudo rmmod algif_aead 2>/dev/null || true
Lưu ý rằng nếu kernel của bản phân phối biên dịch tĩnh tùy chọn CONFIG_CRYPTO_USER_API_AEAD=y, lệnh modprobe trên sẽ không có tác dụng. Vì hầu hết ứng dụng container chỉ dùng thư viện tầng người dùng như OpenSSL chứ không cần giao diện mật mã nội bộ của kernel, hãy cấu hình Seccomp profile mặc định trên Docker, containerd hoặc CRI-O để chặn syscall socket khởi tạo họ AF_ALG (Address Family 38):
{
"defaultAction": "SCMP_ACT_ALLOW",
"syscalls": [
{
"names": ["socket"],
"action": "SCMP_ACT_ERRNO",
"errnoRet": 1,
"args": [
{
"index": 0,
"value": 38,
"op": "SCMP_CMP_EQ"
}
]
}
]
}
Biện pháp này triệt tiêu hoàn toàn đường dẫn tấn công của CVE-2026-31431 ngay cả trên kernel biên dịch tĩnh chưa kịp vá.
2. Đồng Bộ Luồng Ủy Quyền Daemon Và Bật User Namespaces
Để xử lý triệt để CVE-2026-34040, hãy nâng cấp Docker Engine lên tối thiểu 29.3.1 (hoặc Docker Desktop 4.66.1) nhằm đảm bảo body stream luôn được chuyển nguyên vẹn tới AuthZ plugin trước khi lập lịch. Về mặt kiến trúc, tuyệt đối không mở cổng TCP của Docker Daemon trực tiếp ra mạng nội bộ; chỉ giao tiếp qua Unix Domain Socket cục bộ hoặc bọc sau lớp proxy kiểm soát kích thước request có xác thực mTLS. Cuối cùng, hãy kích hoạt User Namespaces (userns) để ánh xạ UID root (0) trong container thành UID không đặc quyền trên host, giữ vững chốt chặn cuối cùng nếu ranh giới phần mềm gặp sự cố.




Đang tải bình luận…