Saravana Kumar
Saravana Kumar

Reputation: 322

Can I use a self-signed SSL certificate with the domain name www.google.com?

What makes my browser believe that there's no "Man in the middle" & trust the Connection is secure? The following is a scenario provided by my mentor to me.

Let's assume that the "man in the middle" has perfectly done ARP spoofing, then did the perfect DNS spoofing & also has a perfect self-signed SSL certificate with the domain name "www.google.com". How does my browser know that it isn't interacting with the bad guy?

I found that it is very easy to get a self-signed certificate with existing domain names, is this even possible?

So in a nutshell, "What is the ultimate trust factor for my browser to believe that it is communicating with a legitimate server? "

Upvotes: 0

Views: 2233

Answers (1)

Patrick Mevzek
Patrick Mevzek

Reputation: 12515

My mentor says that it is very easy to get a self-signed certificate with existing domain names, is this even possible?

Technically, yes, you can create yourself any certificate with any name in it, self signed or signed by a CA you control. It is a one line command with a library like openssl, there is no magic here as this not where the Web PKI derives its authentication feature (this comes from who signs the certificate). You will find plenty of answers in this very own website showing how to generate self-signed certificates for any name of your liking.

The browser will check this certificate received from server (legitimate or hijacked) based on the list of CA it has in the trustore it is using (either its own, or some OS one). By default it will not have any CA that you control, so it will reject this certificate by default. Except if you force it of course, or add your own CA into it.

However this is only half of the story.

HTTP Key pinning

While kind of being deprecated, a webserver can specify which keys were used to create certificates exposed. See https://en.wikipedia.org/wiki/HTTP_Public_Key_Pinning

This appears like that:

$ wget -SO /dev/null https://securedrop.propublica.org

...
Public-Key-Pins: pin-sha256="PJgArNye1xwYWDAy3Og4ud5XTJd4aOvF0bLa0LzIKiw="; pin-sha256="RRM1dGqnDFsCJXBTHky16vi1obOlCgFFn/yOhI/y+ho="; max-age=86400
...

The public key(s) described here are either the one of the end certificate, or one of the intermediate CA certificates or the one of the root certificate.

Now of course, under an active attack, the hijacker could as well modify this HTTP Header so that it contains the key associated with its fake certificate. But here is how the mechanism is supposed to work: we start with the assumption that the valid servers starts to use this feature and provide this header; clients connecting to it should record the header value and keep it during max-age seconds, which is supposed to be a long value. So that on a subsequent visit to the website, the browser can now match the certificate chain it got with whatever pinned keys it remembered for previous time.

Indeed it does not solve the case when you hit the server for the first time, where you do not have anything stored locally. Which is one of the reasons that people lost interest in that way of protecting things.

You can find a lot of horror stories around it at https://news.netcraft.com/archives/2016/03/30/http-public-key-pinning-youre-doing-it-wrong.html

Have a look at: https://pinning-test.badssl.com/ It should trigger an error if everything is setup correctly in your browser (the certificate does not match the keys pinned)

"Private" Key pinning

Some browsers are also shipped with specific keys/certificates in their source code, for some specific "high value" domain names and hence can check that for the certificate they get.

See https://chromium.googlesource.com/chromium/src/net/+/refs/heads/master/http/transport_security_state_static.json for example for Chromium (warning big file).

It has for example:

{
  "name": "google",
  "static_spki_hashes": [
    "GoogleBackup2048",
    "GoogleG2",
    "GoogleG3",
    "GTSCA1O1",
    "GlobalSignRootCA_R2"
  ],
  "bad_static_spki_hashes": [
    "GlobalSignRootCA",
    "GlobalSignExtendedValidationCA",
    "GlobalSignExtendedValidationCA_G2",
    "GlobalSignExtendedValidationCA_SHA256_G2"
  ],
  "report_uri": "http://clients3.google.com/cert_upload_json"
},

So we can probably infer that the browser will refuse to connect to "Google" webpages if the certificate received is not signed by one of the above CA (and will specifically reject some other CAs).

This page for Chromium browser could also be of interest to you: https://chromium.googlesource.com/chromium/src/+/master/docs/security/faq.md

To enable certificate chain validation, Chrome has access to two stores of trust anchors (i.e. certificates that are empowered as issuers). One trust anchor store is the system or public trust anchor store, and the other other is the local or private trust anchor store.

...

Chrome does not perform pin validation when the certificate chain chains up to a private trust anchor. A key result of this policy is that private trust anchors can be used to proxy (or MITM) connections, even to pinned sites. “Data loss prevention” appliances, firewalls, content filters, and malware can use this feature to defeat the protections of key pinning.

Expect-CT

As written in the above Wikipedia page, "Google recommends using the Expect-CT as a safer alternative." This is more or less the same idea, just implemented differently.

CT stands for Certificate Transparency and basically there are servers out there with a collection of all recently issued certificates by all CA that follow CAB Forum requirements (which they need to follow if they want their root to keep being included in browsers). The system is done in such a way that it behaves basically like in append only mode and theoretically it would be hard to modify the content. So one (like a browser) can connect to one of these server and double check that the certificate it got from server is indeed recorded there (this is done either in-band while establishing the TLS connection has the server can send proofs that the certificate is in some CT logs, or the TLS client can check itself doing OCSP checks). If not, it probably means some problem and it should abort the connection.

It is documented at https://httpwg.org/http-extensions/expect-ct.html

You get however the same problem for the first time visit as with the key pinning case.

Have a look at https://invalid-expected-sct.badssl.com/ which should fail if everything is setup properly.

DANE

DANE uses TLSA records in the DNS to let a domain owner specify which certificates (or keys) should be expected when connecting to various services under its domain. It can either specify details about the service end certificate/key or details about the CA signing its certificate.

It has the interest of being generic (not tailored to any specific service) and allowing, or not, depending on one's wish, to depend on the current Web PKI with all known CAs.

However:

  1. To be useful, DNSSEC must be used otherwise attackers can filter or modify TLSA records, hence nullifying the protection
  2. Browsers do not really read these records to use them, it is mostly in the email world for now

Upvotes: 1

Related Questions