Dipende molto da come la vostra applicazione / sito gestisce i certificati e le chiavi pubbliche, cioè quanto spesso ruotano le chiavi e i certificati. Ad esempio, se il tuo sito ruota molto spesso i certificati, dovrai anche aggiornare la tua applicazione spesso anche se stai impiccando il certificato. Considerando che, in questo caso d'uso, il pinning della chiave pubblica sarà un'idea migliore poiché la chiave pubblica associata al certificato rimarrà statica.
Dal link OWASP che hai menzionato nella domanda:
Certificate
The certificate is easiest to pin. You can fetch the certificate out
of band for the website, have the IT folks email your company
certificate to you, use openssl s_client to retrieve the certificate
etc. When the certificate expires, you would update your application.
Assuming your application has no bugs or security defects, the
application would be updated every year or two. At runtime, you
retrieve the website or server's certificate in the callback. Within
the callback, you compare the retrieved certificate with the
certificate embedded within the program. If the comparison fails, then
fail the method or function.
There is a downside to pinning a certificate. If the site rotates its
certificate on a regular basis, then your application would need to be
updated regularly. For example, Google rotates its certificates, so
you will need to update your application about once a month (if it
depended on Google services). Even though Google rotates its
certificates, the underlying public keys (within the certificate)
remain static.
Public Key
Public key pinning is more flexible but a little trickier due to the
extra steps necessary to extract the public key from a certificate. As
with a certificate, the program checks the extracted public key with
its embedded copy of the public key. There are two downsides two
public key pinning. First, its harder to work with keys (versus
certificates) since you usually must extract the key from the
certificate. Extraction is a minor inconvenience in Java and .Net,
buts its uncomfortable in Cocoa/CocoaTouch and OpenSSL. Second, the
key is static and may violate key rotation policies.
Per quanto riguarda il MitM, no, la tua connessione TLS non sarà vulnerabile a nessun attacco MitM se hai implementato correttamente il blocco del certificato. Anche se un utente malintenzionato è in grado di ottenere un certificato valido per il proprio dominio con la stessa chiave pubblica che la propria applicazione ha bloccato (attraverso una CA rouge diciamo), non avrà ancora il corrispondente chiave privata . Pertanto non sarà in grado di creare una connessione TLS valida con l'applicazione (poiché non sarà in grado di eseguire l'handshake TLS stesso).