Kembali
2026/11/10
Kyverno CVE-2026-124440: Saat Policy Engine Justru Menjadi Jalan Pintas ke Cluster Admin
Di Kyverno 1.19.1, tenant yang boleh menulis policy di satu namespace bisa meraih cluster admin. Cara kerja bypass-nya dan yang perlu dicek sebelum upgrade.
Banyak tim menggunakan Kyverno untuk memisahkan tenant di Kubernetes. Kyverno memeriksa setiap objek terhadap policy sebelum API server menyimpannya, dan dapat mengizinkan pemilik namespace menulis policy sendiri untuk namespace mereka. CVE-2026-124440, yang dipublikasikan pada 8 November 2026, menunjukkan bagaimana pendelegasian itu bisa gagal. Di Kyverno 1.19.1, tenant yang hanya boleh membuat policy di namespace-nya sendiri dapat membuat Kyverno bertindak di luar namespace tersebut dan, langkah demi langkah, meraih hak cluster admin.
Perbaikannya sudah tersedia sejak 20 Oktober di Kyverno 1.19.2. Cluster yang melewatkan rilis tersebut masih rentan. Artikel ini menjelaskan apa yang salah, bagaimana eskalasi terjadi, dan apa yang perlu diperiksa di cluster Anda sendiri.
Poin penting
- CVE-2026-124440 (advisory GitHub GHSA-39w8-hv5g-f73w) memengaruhi Kyverno 1.19.1 dan telah diperbaiki di 1.19.2. Catatan CVE memberinya skor 9.4 menurut CVSS 4.0 dan 9.9 menurut CVSS 3.1.
- Penyerang hanya memerlukan izin untuk membuat Kyverno Policy bercakupan namespace di namespace-nya sendiri.
- apiCall pada policy dijalankan sebagai ServiceAccount admission controller Kyverno, yang dapat membaca namespace lain dan membuat admission webhook di seluruh cluster. Jalur inilah yang berujung pada cluster admin.
- Advisory tidak mencantumkan workaround. Upgrade ke 1.19.2, lalu tinjau siapa yang dapat membuat policy dan webhook apa saja yang ada.
- Dari sumber yang kami tinjau, belum ada laporan eksploitasi di dunia nyata.
Apa yang seharusnya dilakukan namespace clamp
Policy Kyverno dapat mengambil data dari Kubernetes API saat mengevaluasi sebuah request. Fitur ini disebut apiCall: sebuah rule menyebutkan urlPath, Kyverno memanggil API server, dan hasilnya dipakai oleh rule tersebut. Panggilan ini dilakukan dengan ServiceAccount milik Kyverno sendiri, bukan dengan izin orang yang menulis policy.
Untuk ClusterPolicy yang berlaku di seluruh cluster dan ditulis oleh administrator platform, hal ini memang diharapkan. Untuk Policy bercakupan namespace, yang boleh ditulis oleh tenant, hal ini menjadi risiko. Advisory sebelumnya (GHSA-c5qq-7g2q-cpqp dan GHSA-5qq8-67g6-4h2w) menunjukkan bahwa Policy bercakupan namespace dapat memakai apiCall untuk membaca namespace lain atau menulis objek bercakupan cluster. Kyverno 1.19.1, yang dirilis pada 10 September 2026, menambahkan “namespace clamp”: sebelum menjalankan panggilan, Kyverno memeriksa bahwa path tetap berada di dalam namespace milik policy itu sendiri.
Di mana pemeriksaan dan tindakan berbeda
Clamp di 1.19.1 tidak memeriksa string yang benar-benar dikirimnya. Menurut advisory, clamp mendekode percent-encoding di urlPath, menormalkan hasilnya (sehingga segmen .. diselesaikan), lalu memeriksa namespace pada salinan yang sudah dibersihkan itu. Request-nya sendiri kemudian dikirim dengan path asli yang mentah.
Cara ini berfungsi selama dekode berhasil. Namun jika path berisi percent-escape yang rusak, misalnya % tunggal di query string di bagian akhir, dekode akan gagal. Dalam kasus itu, kode 1.19.1 beralih memeriksa string mentah yang masih ter-encode. API server tidak memiliki mekanisme cadangan seperti itu. API server mendekode path sepenuhnya lalu merutekan request. Akibatnya, clamp melihat namespace milik tenant, sementara API server melihat segmen .. ter-encode yang keluar dari namespace itu, menuju namespace lain atau ke koleksi bercakupan cluster.
Advisory menekankan bahwa ini adalah satu kelas input, bukan satu payload tertentu. Memblokir satu string literal tidak akan menutup celahnya. Perbaikan yang tahan lama adalah memvalidasi dan mengeksekusi path yang persis sama.
Itulah yang dilakukan 1.19.2. Menurut pembacaan kami atas kode sumber 1.19.2, Kyverno kini membentuk satu bentuk kanonis dari path, menolak path yang tidak dapat dikanonisasi, memeriksa namespace pada bentuk tersebut, dan mengirim bentuk yang sama ke API server. Masalah serupa yang diperbaiki dalam rilis yang sama, CVE-2026-122310 (GHSA-3xfv-vq8x-qhg4), menyalahgunakan perbedaan yang sama antara pemeriksaan pada salinan yang dibersihkan dan request mentah, dengan menyembunyikan segmen ../ di balik # atau ?. Itu adalah CVE terpisah dengan catatannya sendiri.
Rantai eskalasi, langkah demi langkah
Pelapor mendemonstrasikan rantai ini di Kubernetes 1.31 dengan Kyverno 1.19.1 yang diinstal dari chart Helm standar dengan nilai default.
- Membuat Policy bercakupan namespace. Satu-satunya hak tenant adalah membuat
policies.kyverno.iodi namespace-nya sendiri. Policy tersebut berisiapiCalldengan path yang lolos dari clamp tetapi diarahkan ke tempat lain. - Memicunya. Membuat objek biasa apa pun yang cocok dengan policy, misalnya ConfigMap di namespace tenant, membuat Kyverno mengevaluasi rule dan menjalankan panggilan sebagai ServiceAccount admission controller-nya.
- Membaca lintas namespace. Teknik yang sama dapat membaca objek di namespace lain, termasuk Secrets jika deployment Kyverno diizinkan membacanya.
- Menulis webhook di seluruh cluster. ServiceAccount tersebut boleh membuat MutatingWebhookConfiguration dan ValidatingWebhookConfiguration, sehingga tenant dapat mendaftarkan webhook-nya sendiri, yang kemudian mencegat dan mengubah admission request di semua namespace.
- Meraih cluster admin. Advisory menjelaskan penggunaan webhook semacam itu untuk mengubah pod yang dibuat di kube-system dan, dari sana, memberi tenant hak cluster-admin. Hasilnya adalah hilangnya kerahasiaan, integritas, dan ketersediaan secara total.
Tidak diperlukan interaksi pengguna, dan webhook terpicu oleh aktivitas cluster yang normal.
Siapa yang terdampak
Catatan CVE mencantumkan Kyverno 1.19.1 sebagai terdampak dan 1.19.2 sebagai tidak terdampak. Versi sebelum 1.19.1 tidak memiliki bypass khusus ini, karena sama sekali tidak memiliki clamp. Versi-versi tersebut terdampak oleh advisory sebelumnya yang hendak diperbaiki oleh clamp, sehingga bertahan di rilis lama bukanlah alternatif yang aman. Risikonya paling tinggi jika pemilik namespace, pipeline CI, atau portal layanan mandiri diizinkan membuat Kyverno Policy.
Kyverno 1.19.2 dirilis pada 20 Oktober 2026, dan catatan rilisnya mencantumkan 24 advisory keamanan GitHub: 9 kritis, 14 tinggi, dan 1 sedang. Beberapa di antaranya berkaitan dengan validasi path API dan pembatasan namespace. Advisory ini dipublikasikan tiga hari kemudian, pada 23 Oktober, tetapi baik advisory maupun catatan CVE menyebut 1.19.2 sebagai versi yang sudah diperbaiki. Setiap advisory memiliki identifiernya sendiri, jadi cocokkan satu per satu alih-alih memperlakukan seluruhnya sebagai satu CVE.
Apa yang perlu diperiksa di cluster Anda
Pertama, cari tahu versi Kyverno yang benar-benar berjalan, bukan versi yang ada di repositori Git Anda:
kubectl get deployments -n kyverno -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.template.spec.containers[*].image}{"\n"}{end}'
Jika ada tag image v1.19.1, rencanakan upgrade ke 1.19.2 sekarang. Kemudian periksa empat hal:
- Siapa yang dapat membuat Policy bercakupan namespace. Uji identitas tenant secara langsung, dan cari role yang memberikan
policies.kyverno.io, termasuk ClusterRole teragregasi yang menambahkan hak ke role bawaan admin dan edit. - Policy yang sudah ada dan memakai apiCall. Daftarkan semuanya dan tinjau setiap
urlPath, terutama path yang mengandung%,..,?, atau#. - Konfigurasi webhook. Bandingkan daftarnya dengan yang Anda harapkan. Kyverno membuat webhook-nya sendiri, jadi fokuslah pada nama yang tidak Anda kenali dan pada waktu pembuatan yang baru.
- Audit log. Cari request dari ServiceAccount admission controller Kyverno yang membuat konfigurasi webhook atau membaca Secrets di luar pola biasanya.
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
Ganti team-a dengan namespace dan identitas tenant Anda sendiri. Jika Anda menemukan webhook yang tidak dapat dijelaskan di cluster yang pernah menjalankan 1.19.1, perlakukan sebagai kemungkinan insiden: amankan audit log sebelum menghapus apa pun.
Pelajaran yang lebih luas: audit pihak penegak
Admission controller, policy engine, dan operator sering kali merupakan komponen dengan hak paling besar di sebuah cluster. Komponen ini memerlukan hak yang luas untuk menjalankan tugasnya, dan tenant berinteraksi dengannya setiap hari. Hal ini menjadikannya target yang menarik. Dalam kasus ini, model tenancy bergantung pada satu pemeriksaan, dan satu langkah dekode yang ditangani secara berbeda oleh pemeriksaan dan oleh request sudah cukup untuk mematahkannya.
Untuk platform Kubernetes private cloud dan multi-tenant, ada tiga kebiasaan yang membantu. Perlakukan policy engine sebagai bagian dari permukaan serangan dan pantau rilis keamanannya seketat Anda memantau versi Kubernetes. Berikan ServiceAccount-nya hanya hak yang diperlukan, misalnya dengan tidak memberikan izin membaca Secret kecuali ada policy yang membutuhkannya. Dan tinjau fitur apa saja yang dapat dijangkau tenant melalui pendelegasian, karena fitur yang berjalan dengan hak platform mengubah input tenant menjadi tindakan platform.
Sumber
- Advisory keamanan Kyverno GHSA-39w8-hv5g-f73w: Eskalasi ke cluster-admin melalui bypass namespace clamp apiCall v1.19.1 dengan percent-escape yang rusak
- Catatan CVE: CVE-2026-124440
- Advisory VulnCheck: Eskalasi Hak Akses di Kyverno 1.19.1 melalui Bypass Namespace Clamp apiCall
- Perbaikan terkait dalam rilis yang sama, CVE-2026-122310: advisory VulnCheck dan GHSA-3xfv-vq8x-qhg4
- Catatan rilis Kyverno v1.19.2: github.com/kyverno/kyverno/releases/tag/v1.19.2
Global
Japan
Korea
China
Taiwan
Vietnam
Thailand
Portugal
Spain
France
Germany
Egypt
Russia