Open
Description
Request Statement
IOHttpClientAdapter.validateCertificate
runs only after the HTTP
request has already been flushed to the socket.
This means an attacker who can present a publicly trusted certificate for
example.com
will receive the full request body (and often the
headers) before the app’s pinning code gets a chance to abort.
So while the callback can block the response from being delivered to the
caller, it cannot stop leakage of sensitive outbound data.
The behavior breaks the primary use-case for validateCertificate:
certificate / public-key pinning.
Solution Brainstorm
validateCertificate
(or a new early-handshake hook) should be invoked
before any body bytes or HTTP headers are written:
- Open TCP socket
- Start TLS handshake
- Call validateCertificate with the server’s leaf cert
- Only if it returns true finish handshake and write request
- That is how Android’s and iOS ATS / TrustKit hooks work, and
it’s how users expect pinning to behave.