Optional mTLS rejects an untrusted client certificate; Harper's own listener would accept it as unauthorized

Aperta
#63 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
22/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
javascript, rust, typescript

Direzione di ricerca

Start in src/mtls.rs at SymphonyClientVerifier::verify_client_cert, which currently delegates to WebPkiClientVerifier, and at build_ssl_tlv in src/proxy_conn.rs, which writes the PP2 SSL verify field. Read server/serverHelpers/proxyProtocol.ts on the Harper side to confirm how verify maps to authorized. Done means an optional-mTLS route accepts an unverifiable chain, sets verify = 1 without forwarding the chain, and a required route still rejects it during the handshake. This is security-sensitive and needs maintainer review of the design.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Summary

On a route with optional client auth (mtls.requireClientCert: false), symphony rejects a client that presents a certificate it cannot verify, so the TLS handshake fails with unknown_ca. Harper's own TLS listener, with the same optional policy, accepts that client as unauthorized (rejectUnauthorized: Boolean(mtlsRequired), server/http.ts, server/threads/threadServer.js). Such a client could then fall back to basic or token auth. Behind symphony it cannot connect at all.

This matters now because host-manager publishes routes with optional mTLS taken from Harper's own socket metadata (HarperFast/host-manager#254). That PR describes the difference as one that "needs a symphony option".

Where

src/mtls.rs: SymphonyClientVerifier::verify_client_cert passes straight through to WebPkiClientVerifier. client_auth_mandatory() only controls whether a certificate is required, not what happens to one that fails verification.

Harper already handles the other half

server/serverHelpers/proxyProtocol.ts reads the PP2_TYPE_SSL verify field and sets authorized = certPresented && verify == 0. The receiving side needs no change. Today build_ssl_tlv (src/proxy_conn.rs) always writes verify = 0 when a chain is present, because rustls only completes the handshake when the cert verified.

Proposed fix

  • When require_cert is false, verify_client_cert accepts the presented chain. rustls still runs verify_tls12_signature / verify_tls13_signature, which proves the client holds the certificate's private key.
  • After the handshake, verify the peer chain once against the route's CA bundle and record the result for the connection.
  • When verification failed: set PP2_CLIENT_CERT_CONN, write verify = 1, and do not forward the chain. Harper then sees "a cert was presented but not verified" and never receives unverified certificate bytes it might read without checking authorized.
  • Required routes are unchanged: an unverifiable cert is still rejected during the handshake.

Related

  • HarperFast/symphony#62: a route that fails to rebuild keeps its old client-certificate policy. Part 3 of #62 (a route with an empty CA bundle that can still be built) uses the same verifier path. With this change, an empty bundle on an optional route means "every client connects as unauthorized", and on a required route it means "reject every connection".

🤖 Generated with Claude Code

Lingua principale
Rust
Stelle
1
Fork
0
Merge medio
19h 12m
PR unite (30g)
13

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di HarperFast/symphony

Tutte le issue di HarperFast/symphony

Issue simili

Altre issue su Rust

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.