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.
Request Statement
IOHttpClientAdapter.validateCertificateruns only after the HTTPrequest has already been flushed to the socket.
This means an attacker who can present a publicly trusted certificate for
example.comwill receive the full request body (and often theheaders) 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 invokedbefore any body bytes or HTTP headers are written:
it’s how users expect pinning to behave.