Rietta.com Security
You are reading The Rietta Blog, a publication about the web since 2005.

Security Quick-Wins: Use DNS CAA Records to Avoid Fraudulent Certificates

It’s ordinarily possible for a CA to sign a certificate for your domain without properly validating it. We essentially have to trust them to take security seriously and to not make mistakes in their process.

Unfortunately, this has been happening with frightening frequency among major CAs around the world, and user agents can’t immediately distrust some of those CAs because it would break too many legitimate websites for users. This can enable man-in-the-middle atttacks and other nefarious hijinks.

DNS CAA records are just a special DNS entry that lists which certificate authorities are authorized to sign certs for your domain, and they’re honored when present. This system provides standard and easy way for your site to specify to CAs whether they are authorized to issue a cert for your domain. Respecting this directive is now actually mandatory among legitimate public certificate authorities, as of , so it’s worth using for all websites considering how trivial it is to enable, even if it can’t provide a perfect guarantee against fraudulent certificate issuance.

For most sites under most circumstances, there should only be one CA at a time being used to sign certificates for a given web domain, but it’s possible to authorize multiple CAs if appropriate. It’s also possible to use CAA to authorize NO CAs, to prevent unintended issuance of any certs at all, which could be used as further hardening technique whenever your existing certs are still valid and no new certificates are expected.

To enable CAA for your domain, simply add an appropriate CAA record to your domain’s DNS. A typical example should look something like 0 issue "letsencrypt.org". Here’s what the output from dig caa rietta.com currently looks like for our site:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ dig caa rietta.com

; <<>> DiG 9.10.6 <<>> caa rietta.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 7348
;; flags: qr rd ra; QUERY: 1, ANSWER: 7, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;rietta.com.                    IN      CAA

;; ANSWER SECTION:
rietta.com.             300     IN      CAA     0 issuewild "comodoca.com"
rietta.com.             300     IN      CAA     0 issuewild "digicert.com"
rietta.com.             300     IN      CAA     0 issuewild "globalsign.com"
rietta.com.             300     IN      CAA     0 issue "letsencrypt.org"
rietta.com.             300     IN      CAA     0 issue "comodoca.com"
rietta.com.             300     IN      CAA     0 issue "digicert.com"
rietta.com.             300     IN      CAA     0 issue "globalsign.com"

;; Query time: 57 msec
;; SERVER: 2601:483:4a80:1800::1#53(2601:483:4a80:1800::1)
;; WHEN: Mon Jul 23 15:33:59 CDT 2018
;; MSG SIZE  rcvd: 275

We added an entry for Let’s Encrypt manually and Cloudflare auto-configured the rest for us to support their automated TLS management.

Before executing this change, I recommend reading up a little more about the specific options available. The Wikipedia article on DNS Certificate Authority Authorization is a reasonable starting point in my opinion. Adding and verifying the DNS entry should be fairly trivial for most sites, as seen in my example above, and shoudn’t be too tricky to plan correctly even for sites with more specialized requirements such as supporting multiple authorities or wildcard certs.

About Brandon Dees

Brandon Dees' photo

Brandon Dees is a full-time Ruby on Rails developer on the Rietta team. Having worked with us since 2012, he has been pivotal in shaping our test driven development practices and shaping our remote pair programming practice that delivers solid, stable software time and time again.