Questo è un problema che non dovrebbe essere affrontato a livello JavaScript, ma a livello TLS. Esistono già due meccanismi che dovrebbero rendere un MITM più difficile:
-
Quando un certificato viene rilasciato da un'autorità di certificazione, la CA deve verificare l'identità del titolare del certificato. A condizione che tutte le CA attendibili da un browser emettano solo certificati con verifica adeguata, ciò significa che verrebbero rilevati eventuali certificati fraudolenti. Sfortunatamente, questo non regge abbastanza. Alcune CA hanno rilasciato certificati senza convalida, ad es. per il test. Altri potrebbero essere costretti dai governi a emettere un certificato che può essere utilizzato per il MITM. Infine, una CA stessa può essere compromessa e un certificato di root rubato può essere utilizzato per firmare certificati dannosi che potrebbero essere considerati attendibili da qualsiasi browser che si fida della CA compromessa.
I certificati errati potrebbero anche essere utilizzati dal software di ispezione deep packet per re-firmare i dati che fluiscono attraverso di esso, ma ciò richiede che tutti i client dietro quel firewall si fidino del certificato utilizzato per la nuova firma. La soluzione "corretta" è non fidarsi di quel certificato.
-
Il blocco dei certificati consente a un sito di dichiarare un certificato valido per un determinato periodo di tempo tramite le intestazioni HTTP. Il browser può memorizzare l'impronta digitale e può confrontare le connessioni successive con il certificato aggiunto. Funziona solo se la prima connessione non era MITM e se il sito utilizza effettivamente il pinning del certificato. Ad esempio, il blocco dei certificati non sarà di aiuto quando viene utilizzato solo in una rete Intranet aziendale in cui tutto il traffico in uscita è MITM.
Alcuni sistemi eseguono il pinning del certificato codificando una chiave pubblica all'interno di un binario. Questo viene fatto da varie app e browser mobili, che consente anche la prima connessione sicura, a condizione che il binario non sia stato compromesso.
Potrebbe essere possibile implementare qualcosa come il pinning dei certificati in JavaScript, ma poiché richiede un server cooperante per inviare le intestazioni richieste, questa non è una soluzione generale. Se ti trovi nella situazione in cui ti fidi di un certificato che non vuoi fidarti, non c'è un modo valido per risolverlo o rilevarlo.