Skip to content

fix: validate kubelet-serving CSRs before auto-approval - #459

Open
xavpaice wants to merge 3 commits into
mainfrom
fix/validate-kubelet-serving-csrs
Open

xavpaice wants to merge 3 commits into
mainfrom
fix/validate-kubelet-serving-csrs

Conversation

@xavpaice

@xavpaice xavpaice commented Sep 8, 2026

Copy link
Copy Markdown
Member

Fixes GHSA-x7j5-fww5-mqmv.

reconcileCertificateSigningRequests previously approved any pending kubernetes.io/kubelet-serving CSR without inspecting the requester, the certificate request, or the node. This allowed any principal that can create a CSR to obtain a cluster-CA-signed certificate for arbitrary names, including the Kubernetes API server.

The approval logic now validates:

  • Spec.Usages matches the expected kubelet-serving set.
  • The embedded x509 request subject has O=system:nodes and CN=system:node:<nodeName>.
  • The authenticated requester (Spec.Username) equals the certificate CommonName.
  • The CSR does not include EmailAddresses or URIs.
  • The named Node exists in the cluster.
  • Every DNS name and IP address in the CSR appears in node.Status.Addresses.

Invalid CSRs are skipped with a debug log; only valid ones are approved.

Testing

  • Added regression tests in pkg/ekcoops/csr_test.go covering valid CSRs and the attack cases described in the advisory.
  • Added a manual cluster testing guide in docs/testing-kubelet-csr-rotation.md.
  • make test passes: lint, vet, and go test ./pkg/... ./cmd/....
  • make build succeeds.

This prevents any principal that can create a CertificateSigningRequest from obtaining a cluster-CA-signed certificate for arbitrary names such as the Kubernetes API server.

The approval logic now checks the requester identity, subject organization/CommonName, usages, and that every requested SAN belongs to the named node.

Relates to GHSA-x7j5-fww5-mqmv.

Also adds regression tests and a manual cluster testing guide.
@xavpaice
xavpaice requested a review from a team as a code owner September 8, 2026 04:40
…tstrap

The previous guide assumed kubelet serving cert rotation was already enabled.

Add a check of /var/lib/kubelet/pki and instructions to enable serverTLSBootstrap: true when kubelet-server-*.pem files are absent.

Relates to GHSA-x7j5-fww5-mqmv.
Real kubelet serving CSRs generated with ECDSA keys only request

digital signature and server auth, not key encipherment.

Validate that server auth is present, that all usages belong to the

kubelet-serving set, and reject any extra usages instead of requiring

the exact three-entry set.

Relates to GHSA-x7j5-fww5-mqmv.
@xavpaice
xavpaice marked this pull request as draft September 8, 2026 07:20
@xavpaice
xavpaice marked this pull request as ready for review September 8, 2026 07:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant