Skip to content

web: reject a client CA that holds no certificates - #438

Open
mrueg wants to merge 1 commit into
prometheus:masterfrom
mrueg:fix/client-ca-file-no-certificates
Open

web: reject a client CA that holds no certificates#438
mrueg wants to merge 1 commit into
prometheus:masterfrom
mrueg:fix/client-ca-file-no-certificates

Conversation

@mrueg

@mrueg mrueg commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

x509.CertPool.AppendCertsFromPEM reports whether it parsed any certificate at all, and both call sites discard it. A client_ca_file that exists but holds no usable PEM — a truncated copy, a DER-encoded file, a path pointing at the wrong artifact — is accepted and produces a pool with no subjects. The same applies to an inline client_ca.

Under RequireAndVerifyClientCert this fails closed, so it is not an authentication bypass. But the operator gets a server that rejects every client with an opaque handshake error, while Validate reports the configuration as good.

Reproduced against master: a CA file containing the literal text this is definitely not a PEM certificate was accepted, and the resulting pool had 0 subjects.

Ordering

The emptiness check runs after the client auth policy has been validated. Two existing fixtures pin the ordering from opposite directions — one configures a readable but empty CA with no policy and expects the policy error, the other configures a missing CA file with no policy and expects the read error. Reporting emptiness last keeps both reporting what they did before.

Tests

web_config_auth_clientCAs_invalid.bad.yml only covers a missing file, which is why this went unnoticed. Added fixtures for a file that parses to nothing and for the inline equivalent; both fail against master.

🤖 Generated with Claude Code

x509.CertPool.AppendCertsFromPEM reports whether it parsed any certificate
at all, and both call sites discarded it. A client_ca_file that exists but
holds no usable PEM - a truncated copy, a DER encoded file, a path pointing
at the wrong artifact - was accepted, and produced a pool with no subjects.
The same applied to an inline client_ca.

Under RequireAndVerifyClientCert that fails closed, so it is not an
authentication bypass, but the operator gets a server that rejects every
client with an opaque handshake error while Validate reports the
configuration as good. Reject it at configuration time instead, naming the
file so the cause is obvious.

The emptiness check runs after the client auth policy has been validated.
Two existing fixtures pin the ordering from opposite directions: one
configures a readable but empty CA with no policy and expects the policy
error, the other configures a missing CA file with no policy and expects
the read error. Reporting emptiness last keeps both reporting what they
did before, and reports the more fundamental fault first when a
configuration carries several.

The existing web_config_auth_clientCAs_invalid.bad.yml fixture only covers
a missing file, which is why this went unnoticed, so add fixtures for a
file that parses to nothing and for the inline equivalent.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Manuel Rüger <manuel@rueg.eu>
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