Quay lại
2026/11/10
Kyverno CVE-2026-124440: khi công cụ chính sách trở thành lối vòng lên quyền quản trị cụm
Trong Kyverno 1.19.1, tenant chỉ được viết chính sách trong một namespace có thể chiếm quyền quản trị cụm. Cơ chế bypass và những gì cần kiểm tra trước khi nâng cấp.
Nhiều đội ngũ dùng Kyverno để tách biệt các tenant trong Kubernetes. Kyverno kiểm tra mọi đối tượng theo chính sách trước khi API server lưu lại, và có thể cho phép chủ sở hữu namespace tự viết chính sách cho namespace của mình. CVE-2026-124440, công bố ngày 8 tháng 11 năm 2026, cho thấy cơ chế ủy quyền này có thể thất bại như thế nào. Trong Kyverno 1.19.1, một tenant chỉ được phép tạo chính sách trong namespace của chính mình có thể khiến Kyverno hành động bên ngoài namespace đó và, từng bước một, đạt được quyền quản trị cụm.
Bản vá đã có từ ngày 20 tháng 10 trong Kyverno 1.19.2. Các cụm đã bỏ qua bản phát hành đó vẫn đang bị phơi nhiễm. Bài viết này giải thích lỗi nằm ở đâu, quá trình leo thang đặc quyền diễn ra thế nào, và những gì cần kiểm tra trong cụm của bạn.
Những điểm chính
- CVE-2026-124440 (khuyến cáo GitHub GHSA-39w8-hv5g-f73w) ảnh hưởng đến Kyverno 1.19.1 và đã được khắc phục trong 1.19.2. Bản ghi CVE chấm 9.4 theo CVSS 4.0 và 9.9 theo CVSS 3.1.
- Kẻ tấn công chỉ cần quyền tạo một Kyverno Policy phạm vi namespace trong namespace của chính mình.
- apiCall của chính sách chạy dưới ServiceAccount của admission controller Kyverno, vốn có thể đọc các namespace khác và tạo admission webhook trên toàn cụm. Con đường đó dẫn tới quyền quản trị cụm.
- Khuyến cáo không đưa ra biện pháp tạm thời nào. Hãy nâng cấp lên 1.19.2, sau đó rà soát ai có thể tạo chính sách và những webhook nào đang tồn tại.
- Trong các nguồn chúng tôi đã xem xét, chưa có báo cáo nào về việc khai thác thực tế.
Cơ chế giới hạn namespace lẽ ra phải làm gì
Chính sách Kyverno có thể lấy dữ liệu từ Kubernetes API trong khi đánh giá một yêu cầu. Tính năng này gọi là apiCall: một quy tắc chỉ định một urlPath, Kyverno gọi API server, và kết quả được đưa vào quy tắc. Lời gọi được thực hiện bằng ServiceAccount của chính Kyverno, chứ không phải bằng quyền của người viết chính sách.
Với ClusterPolicy áp dụng toàn cụm, do quản trị viên nền tảng viết, điều này là bình thường. Với Policy phạm vi namespace, loại mà tenant có thể được phép viết, đây là một rủi ro. Các khuyến cáo trước đó (GHSA-c5qq-7g2q-cpqp và GHSA-5qq8-67g6-4h2w) đã chỉ ra rằng một Policy phạm vi namespace có thể dùng apiCall để đọc các namespace khác hoặc ghi các đối tượng phạm vi cụm. Kyverno 1.19.1, phát hành ngày 10 tháng 9 năm 2026, đã bổ sung một cơ chế “giới hạn namespace” (namespace clamp): trước khi thực hiện lời gọi, Kyverno kiểm tra rằng đường dẫn vẫn nằm trong namespace của chính sách.
Nơi bước kiểm tra và hành động thực tế tách rời nhau
Cơ chế giới hạn trong 1.19.1 không kiểm tra chuỗi mà nó thực sự gửi đi. Theo khuyến cáo, nó giải mã percent-encoding trong urlPath, chuẩn hóa kết quả (để các đoạn .. được phân giải), rồi kiểm tra namespace trên bản sao đã làm sạch đó. Trong khi đó, bản thân yêu cầu lại được gửi đi với đường dẫn gốc, chưa qua xử lý.
Cách này hoạt động được miễn là việc giải mã thành công. Nhưng nếu đường dẫn chứa một chuỗi thoát phần trăm sai định dạng, chẳng hạn một ký tự % đứng riêng trong chuỗi truy vấn ở cuối, việc giải mã sẽ thất bại. Khi đó, mã của 1.19.1 quay về kiểm tra chuỗi gốc vẫn còn ở dạng mã hóa. API server không có cơ chế quay lui như vậy. Nó giải mã đầy đủ đường dẫn và định tuyến yêu cầu. Vì vậy, cơ chế giới hạn thấy namespace của chính tenant, trong khi API server lại thấy các đoạn .. đã mã hóa thoát ra khỏi namespace đó, sang một namespace khác hoặc tới một tập hợp tài nguyên phạm vi cụm.
Khuyến cáo nhấn mạnh rằng đây là cả một lớp đầu vào, không phải một payload duy nhất. Chặn một chuỗi cụ thể sẽ không giải quyết được vấn đề. Cách khắc phục bền vững là kiểm tra và thực thi chính xác cùng một đường dẫn.
Đó chính là điều 1.19.2 thực hiện. Theo cách chúng tôi đọc mã nguồn 1.19.2, Kyverno giờ đây tạo một dạng chuẩn duy nhất của đường dẫn, từ chối những đường dẫn không thể chuẩn hóa, kiểm tra namespace trên dạng đó và gửi chính dạng đó tới API server. Một lỗi liên quan được sửa trong cùng bản phát hành, CVE-2026-122310 (GHSA-3xfv-vq8x-qhg4), lợi dụng cùng sự chênh lệch giữa bước kiểm tra trên bản đã làm sạch và yêu cầu gốc bằng cách giấu các đoạn ../ phía sau # hoặc ?. Đó là một CVE riêng với bản ghi riêng.
Chuỗi leo thang đặc quyền, từng bước
Người báo cáo đã trình diễn chuỗi tấn công trên Kubernetes 1.31 với Kyverno 1.19.1 được cài đặt từ Helm chart chuẩn với các giá trị mặc định.
- Tạo một Policy phạm vi namespace. Đặc quyền duy nhất của tenant là tạo
policies.kyverno.iotrong namespace của chính mình. Chính sách chứa mộtapiCallcó đường dẫn vượt qua được cơ chế giới hạn nhưng lại được định tuyến đến nơi khác. - Kích hoạt chính sách. Chỉ cần tạo bất kỳ đối tượng thông thường nào khớp với chính sách, chẳng hạn một ConfigMap trong namespace của tenant, Kyverno sẽ đánh giá quy tắc và thực hiện lời gọi dưới danh nghĩa ServiceAccount admission controller của nó.
- Đọc dữ liệu xuyên namespace. Cùng kỹ thuật này có thể đọc các đối tượng trong namespace khác, bao gồm cả Secrets nếu bản triển khai Kyverno được phép đọc chúng.
- Ghi một webhook toàn cụm. ServiceAccount này có thể tạo MutatingWebhookConfigurations và ValidatingWebhookConfigurations, vì vậy tenant có thể đăng ký webhook của riêng mình, webhook này sau đó chặn và sửa đổi các yêu cầu admission trong mọi namespace.
- Đạt quyền quản trị cụm. Khuyến cáo mô tả việc dùng một webhook như vậy để thay đổi các pod được tạo trong kube-system và từ đó cấp cho tenant quyền cluster-admin. Kết quả là mất hoàn toàn tính bảo mật, tính toàn vẹn và tính sẵn sàng.
Không cần bất kỳ tương tác nào từ người dùng, và webhook được kích hoạt bởi hoạt động bình thường của cụm.
Ai bị ảnh hưởng
Bản ghi CVE liệt kê Kyverno 1.19.1 là bị ảnh hưởng và 1.19.2 là không bị ảnh hưởng. Các phiên bản trước 1.19.1 không có lỗ hổng bypass cụ thể này, vì chúng hoàn toàn không có cơ chế giới hạn. Tuy nhiên, chúng bị ảnh hưởng bởi các khuyến cáo trước đó mà cơ chế giới hạn được tạo ra để khắc phục, nên ở lại phiên bản cũ không phải là một lựa chọn an toàn. Rủi ro cao nhất ở những nơi chủ sở hữu namespace, pipeline CI hoặc cổng tự phục vụ được phép tạo Kyverno Policy.
Kyverno 1.19.2 được phát hành ngày 20 tháng 10 năm 2026, và ghi chú phát hành liệt kê 24 khuyến cáo bảo mật GitHub: 9 mức nghiêm trọng (critical), 14 mức cao và 1 mức trung bình. Một số trong đó liên quan đến kiểm tra đường dẫn API và giới hạn trong namespace. Khuyến cáo này được công bố ba ngày sau, vào ngày 23 tháng 10, nhưng cả khuyến cáo lẫn bản ghi CVE đều ghi 1.19.2 là phiên bản đã khắc phục. Mỗi khuyến cáo có mã định danh riêng, vì vậy hãy đối chiếu từng cái một thay vì coi cả loạt như một CVE duy nhất.
Những gì cần kiểm tra trong cụm của bạn
Trước tiên, hãy xác định phiên bản Kyverno đang thực sự chạy, chứ không phải phiên bản trong kho Git của bạn:
kubectl get deployments -n kyverno -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.template.spec.containers[*].image}{"\n"}{end}'
Nếu có bất kỳ image tag nào là v1.19.1, hãy lên kế hoạch nâng cấp lên 1.19.2 ngay. Sau đó kiểm tra bốn điểm:
- Ai có thể tạo Policy phạm vi namespace. Kiểm thử trực tiếp bằng danh tính của tenant, và tìm các role cấp quyền
policies.kyverno.io, kể cả các ClusterRole tổng hợp (aggregated) bổ sung quyền vào các role admin và edit có sẵn. - Các chính sách hiện có dùng apiCall. Liệt kê chúng và rà soát mọi
urlPath, đặc biệt là các đường dẫn chứa%,..,?hoặc#. - Cấu hình webhook. So sánh danh sách với những gì bạn mong đợi. Kyverno tự tạo webhook của riêng nó, vì vậy hãy tập trung vào những tên bạn không nhận ra và thời điểm tạo gần đây.
- Nhật ký kiểm toán. Tìm các yêu cầu từ ServiceAccount admission controller của Kyverno tạo cấu hình webhook hoặc đọc Secrets khác với hành vi thông thường của nó.
kubectl auth can-i create policies.kyverno.io -n team-a --as=system:serviceaccount:team-a:default
kubectl get policies.kyverno.io -A -o json | jq -r '.items[] | select([.spec.rules[]?.context[]? | select(.apiCall)] | length > 0) | "\(.metadata.namespace)/\(.metadata.name)"'
kubectl get mutatingwebhookconfigurations,validatingwebhookconfigurations -o custom-columns=NAME:.metadata.name,CREATED:.metadata.creationTimestamp
Thay team-a bằng namespace và danh tính tenant của bạn. Nếu bạn phát hiện một webhook không giải thích được trên một cụm từng chạy 1.19.1, hãy coi đó là một sự cố có thể đã xảy ra: lưu giữ nhật ký kiểm toán trước khi xóa bất cứ thứ gì.
Bài học rộng hơn: hãy kiểm toán chính thành phần thực thi
Admission controller, công cụ chính sách và operator thường là những thành phần có đặc quyền cao nhất trong cụm. Chúng cần quyền rộng để làm việc, và tenant tương tác với chúng hằng ngày. Điều đó khiến chúng trở thành mục tiêu hấp dẫn. Trong trường hợp này, mô hình đa tenant phụ thuộc vào một bước kiểm tra duy nhất, và chỉ một bước giải mã được bước kiểm tra và yêu cầu xử lý khác nhau là đủ để phá vỡ nó.
Với các nền tảng Kubernetes đám mây riêng và đa tenant, có ba thói quen hữu ích. Hãy coi công cụ chính sách là một phần của bề mặt tấn công và theo dõi các bản phát hành bảo mật của chúng sát sao như phiên bản Kubernetes. Chỉ cấp cho ServiceAccount của chúng những quyền cần thiết, ví dụ không cấp quyền đọc Secret trừ khi một chính sách cần đến. Và hãy rà soát những tính năng mà tenant có thể tiếp cận qua cơ chế ủy quyền, vì một tính năng chạy với đặc quyền của nền tảng sẽ biến đầu vào của tenant thành hành động của nền tảng.
Nguồn tham khảo
- Khuyến cáo bảo mật Kyverno GHSA-39w8-hv5g-f73w: Leo thang lên cluster-admin qua việc bypass cơ chế giới hạn namespace của apiCall trong v1.19.1 bằng chuỗi thoát phần trăm sai định dạng
- Bản ghi CVE: CVE-2026-124440
- Khuyến cáo của VulnCheck: Leo thang đặc quyền trong Kyverno 1.19.1 qua việc bypass cơ chế giới hạn namespace của apiCall
- Bản vá liên quan trong cùng bản phát hành, CVE-2026-122310: khuyến cáo của VulnCheck và GHSA-3xfv-vq8x-qhg4
- Ghi chú phát hành Kyverno v1.19.2: github.com/kyverno/kyverno/releases/tag/v1.19.2
Global
Japan
Korea
China
Taiwan
Thailand
Indonesia
Portugal
Spain
France
Germany
Egypt
Russia