CVE-2020-8561 and DNS proxy TOCTOU risk

CVE-2020-8561 and DNS proxy TOCTOU risk

CVE-2020-8561 sits in the request path of the API server DNS proxy, where the same name is resolved twice before the request is sent on. That leaves a narrow timing window for a time-of-check, time-of-use race. The first lookup decides whether the destination looks acceptable. The second lookup decides where the traffic actually lands.

That kind of bug is awkward for security tooling because there is no neat patched binary to point at. The issue is tied to behaviour, not just version number. A scanner that trusts the wrong fixed field can miss the exposure entirely.

Fixed version fields and unfixed CVEs

Older Kubernetes CVE records included fixed version fields that were not accurate for these cases. The records for CVE-2020-8561, CVE-2020-8562, CVE-2021-25740 and CVE-2020-8554 were updated on 1 June 2026 to reflect that the affected issues remain unfixed or need standardised version formatting.

That is not a cosmetic detail. Vulnerability scanners and feed consumers often treat a fixed version as the boundary between affected and clean. If that boundary is wrong, the result is a false negative with a straight face.

What OSV files change for scanners and feeds

OSV files make the metadata more machine-readable, which is useful until the underlying record is wrong. Kubernetes has been generating official OSV files from these CVE records, so any incorrect fixed tag gets copied into the feed path scanners depend on.

That matters because many tools do not reason about whether a finding is patchable, mitigable, or simply structural. They compare versions, mark the host, and move on. For unfixed CVEs, that can turn a real exposure into a green tick.

Where the DNS proxy race sits in the request path

The API server proxy resolves a destination, checks it, then resolves again when the request is made. That second resolution is the weak point. A malicious DNS change between those two lookups can push traffic somewhere the first decision did not intend.

This is not a theory built on tidy lab conditions. The timing window is narrow, which is exactly why it survives casual review. It is the kind of thing that disappears under normal testing and reappears when traffic, caching, and resolver behaviour line up badly.

Two lookups, one decision, and a narrow timing window

The proxy has to decide whether a target IP is acceptable before it forwards the request. If the name is resolved twice, the decision and the destination can drift apart. That is classic TOCTOU territory.

For operators, the useful detail is the failure mode, not the abstract race name. The risk is that a request allowed for one IP can end up at another. A scanner will not tell you that. A packet trace might.

Why pinning the IP is not a clean answer

Freezing the resolved IP sounds neat until split-horizon DNS or changing backends enter the room. Real environments often rely on names that resolve differently inside and outside a cluster, or move between addresses as services shift.

Pinning the first IP would remove the race, but it would also break valid setups. That is why the fix path is operational rather than purely code-based. The awkward bit is the one that survives the tidy answer.

How to read the operational boundary instead of hunting for a patch

Some Kubernetes CVE records point at controls rather than patched releases. That is the clue. For CVE-2020-8561, the useful boundary is where the API server can still be tricked into talking to something it should not trust, and where the rest of the control plane can be kept boring.

The practical answer is to reduce what the API server can reach, reduce what it can leak, and cut broad write access that turns a narrow bug into a wider mess.

Local caching resolvers for the API server

A local caching resolver such as dnsmasq keeps DNS answers stable for the API server and reduces the chance of resolver churn during a request. Kubernetes notes dnsmasq with a cache TTL setting as the operational control here.

That is not magic, and it does not turn a bad trust model into a good one. It narrows the moving parts. If the API server is making repeated DNS decisions, a local cache cuts the chances of the answer changing between checks.

RBAC and log-level checks that cut off the wider blast radius

Some of the surrounding Kubernetes issues are not about DNS at all. Broad write access to Endpoints and EndpointSlices can let traffic be pointed across namespace boundaries. Older upgraded clusters may still carry those permissions in aggregate roles, which is a lovely gift from history.

RBAC review matters here because the default edit and admin ClusterRoles stopped including those permissions from Kubernetes 1.22 onwards. On upgraded clusters, the system:aggregate-to-edit ClusterRole still needs a look, and kubectl auth reconcile can remove Endpoints write access where it should not exist.

Logging is another low-grade risk. Setting kube-apiserver to --v < 10 keeps log verbosity down, and --profiling=false removes another route for unauthorised changes or exposure. The point is not tidiness. It is stopping a small control-plane issue from becoming a broad readout of response bodies and internal behaviour.

For CVE records like these, the clean version number is less useful than the operational boundary. The scanner may miss it, but the cluster will still behave exactly as configured.

Related posts

headscale | v0.29.7

Headscale v0 29 7 security release: upgrade to v0 29 7, update Tailscale to v1 104 4 or newer, disable SSH agent and port forwarding per node until update

ionCube Loader: offline PHP bytecode decryption

ionCube Loader is not magic, just a native PHP extension with a very hard boundary. Once you trace the entrypoint and the key derivation properly, the supposed mystery turns into a pile of exacting...

Vault | v2.2.1

Vault v2 2 1: maintenance patch with regression fixes, stability and correctness improvements, upgrade guidance, verify downloads and report regressions