What exactly do you mean by a "TLS MITM" attack? afaik most attempts at doing a MitM during a TLS handshake will simply cause the handshake to fail, so I doubt it'd ever reach Javascript-land in the first place. In that sense the "standard mechanism" is the TLS protocol/handshake itself. But I don't think that's the answer you're after?
– IxrecMar 13 '16 at 17:53

1

@Ixrec I am specifically think of environments where an organisation has its own CA installed on standard builds, and uses a TLS interception proxy that re-signs content. I frown on this practice, but expect it to grow with http2 browser implementations mandating TLS.
– Phil LelloMar 13 '16 at 17:59

1

Ah, interesting. That sounds like a good question for security.stackexchange.com; they'd know far better than we would if this sort of thing is possible. But my impression is that the only detectable change is that you get "the wrong" certificate, and the only way to know it's the wrong one is to hardcode which CAs you do and don't trust. Which I doubt JS has any mechanism for; that's generally a browser-level or OS-level issue.
– IxrecMar 13 '16 at 18:05

I think DNSSEC is an attempt to mitigate this, but of course, a big/rich/determined enough entity can probably tinker with code for anything. I know Microsoft used to give source to at least one investment bank.
– Phil LelloMar 13 '16 at 18:13

1 Answer
1

This is a problem that should not be tackled on a JavaScript level, but on the TLS level. There are two mechanisms already in place that should make a MITM more difficult:

When a cert is issued by a certificate authority, the CA should verify the identity of the certificate holder. Provided that all CAs trusted by a browser only issue certs with proper verification, this means any fraudulent certs would be detected. Unfortunately, this doesn't quite hold. Some CAs have issued certs without validation, e.g. for testing. Others might be compelled by governments to issue a cert that can then be used for MITM. Finally, a CA itself can be compromised, and a stolen root certificate be used to sign malicious certs which would be trusted by any browser trusting the compromised CA.

Wrong certificates might also be used by deep packet inspection software to re-sign data flowing through it, but that requires all clients behind that firewall to trust the certificate used for re-signing. The “correct” solution is to not trust that cert.

Certificate pinning allows a site to declare a certificate to be valid for a certain time frame via HTTP headers. The browser can store the fingerprint, and can compare subsequent connections to the pinned certificate. This only works if the first connection was not MITM'ed, and if the site actually uses certificate pinning. For example, certificate pinning will not help when it is only used in a corporate intranet where all outgoing traffic is MITM'ed.

Some systems do certificate pinning by hard-coding a public key inside a binary. This is done by various mobile apps and browsers, which allows the first connection to be secure as well, provided the binary was not compromised.

It might be possible to implement something like certificate pinning in JavaScript, but since it requires a cooperating server to send the required headers, this is not a general solution. If you're in the situation that you're trusting a cert you don't want to trust, there's just no good way to resolve or detect that.

If one party to a communication (Bob) in controlled by a third party (Eve), there's no need for Bob to issue a certificate that allows a MItM attack. Eve can simply obtain the contents of the communication directly from Bob.
– kevin clineApr 12 '16 at 20:07