dio icon indicating copy to clipboard operation
dio copied to clipboard

validateCertificate callback fires after request body is sent, so true TLS-pinning is impossible

Open maeddin opened this issue 6 months ago • 1 comments

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.

maeddin avatar Jul 03 '25 15:07 maeddin

Could you make a PoC using the dio library so we can understands this correctly?

AlexV525 avatar Jul 03 '25 16:07 AlexV525