Search code examples
opensslssl-certificatex509certificate2

X.509 certificate: Is it a good idea (or bad) to add localhost in Subject Alternative Name?


We are deciding whether "localhost" (and similarly address like "127.0.0.1") should be added as one of the subject alternative names in the certificate. One benefit might be to facilitate local testing. But will there be any drawback?


Solution

  • Is it a good idea (or bad) to add localhost in Subject Alternative Name?

    It depends on the standards you follow and your security posture.


    First things first (for the discussion below). A Fully Qualified Domain Name (FQDN) must be defined. That definition is taken from W. Richard Steven's TCP/IP Illustrated Volume I: The Protocols (p. 189):

    A domain name that ends with a period is called an absolute domain name or a fully qualified domain name. If the domain name does not end in a period, it is assumed that name needs to be completed. How the name is completed depends upon the DNS software being used.

    That means we can change localhost into a fully qualified domain name by appending a period:

    localhost.
    

    Here's a little experiment:

    $ hostname
    debian-q500
    
    $ hostname --fqdn
    debian-q500
    
    $ dnsdomainname 
    $
    
    $ ping debian-q500.
    ping: unknown host debian-q500.
    $ ping debian-q500.local
    PING debian-q500.local (172.16.1.26) 56(84) bytes of data.
    64 bytes from debian-q500.home.pvt (172.16.1.26): icmp_req=1 ttl=64 time=0.040 ms
    64 bytes from debian-q500.home.pvt (172.16.1.26): icmp_req=2 ttl=64 time=0.035 ms
    ...
    
    $ ping localhost.
    PING localhost (127.0.0.1) 56(84) bytes of data.
    64 bytes from localhost (127.0.0.1): icmp_req=1 ttl=64 time=0.033 ms
    64 bytes from localhost (127.0.0.1): icmp_req=2 ttl=64 time=0.037 ms
    ...
    $ ping localhost.local
    ping: unknown host localhost.local
    $ ping localhost.localdomain
    ping: unknown host localhost.localdomain
    

    Next is standards. One of the most popular is the guides published by the CAs ad Browsers. The CAs ad Browsers publish their operations guides at the CA/B Forums. They two guides of interest are:

    There's another popular one, but it generally defers CA/B guides in hosts listed in the certificates. That standard is RFC 5280 from the IETF:

    RFC 5280 will call out other items, like how to validate a certificate chain and how to list email addresses in the subjectAltName.

    Baseline Guide

    The Baseline guide has this to say about names:

    9.2.1 Subject Alternative Name Extension    
    Certificate Field: extensions:subjectAltName
    Required/Optional: Required
    
    Contents: This extension MUST contain at least one entry. Each
    entry MUST be either a dNSName containing the Fully-Qualified
    Domain Name or an iPAddress containing the IP address of a
    server. The CA MUST confirm that the Applicant controls the
    Fully-Qualified Domain Name or IP address or has been granted
    the right to use it by the Domain Name Registrant or IP address
    assignee, as appropriate.
    
    Wildcard FQDNs are permitted.
    ...
    

    And

    9.2.2 Subject Common Name Field 
    Certificate Field: subject:commonName (OID 2.5.4.3)
    Required/Optional: Deprecated (Discouraged, but not prohibited)
    
    Contents: If present, this field MUST contain a single IP address or
    Fully-Qualified Domain Name that is one of the values contained in
    the Certificate’s subjectAltName extension (see Section 9.2.1).
    

    Finally,

    11.1.3 Wildcard Domain Validation   
    
    Before issuing a certificate with a wildcard character (*) in a
    CN or subjectAltName of type DNS-ID, the CA MUST establish and
    follow a documented procedure† that determines if the wildcard
    character occurs in the first label position to the left of a
    “registry-controlled” label or “public suffix” (e.g. “*.com”,
    “*.co.uk”, see RFC 6454 Section 8.2 for further explanation).
    
    If a wildcard would fall within the label immediately to the left
    of a registry-controlled† or public suffix, CAs MUST refuse
    issuance unless the applicant proves its rightful control of the
    entire Domain Namespace. (e.g. CAs MUST NOT issue “*.co.uk” or
    “*.local”, but MAY issue “*.example.com” to Example Co.).
    

    So localhost is fine as long as its a fully qualified domain name. In fact, localhost not even mentioned in the guide.

    Extended Validation

    9.2.2 Subject Alternative Name Extension
    Certificate field: subjectAltName:dNSName
    Required/Optional: Required
    
    Contents: This extension MUST contain one or more host Domain
    Name(s) owned or controlled by the Subject and to be associated
    with the Subject’s server. Such server MAY be owned and operated
    by the Subject or another entity (e.g., a hosting service).
    Wildcard certificates are not allowed for EV Certificates.
    
    9.2.3 Subject Common Name Field
    Certificate field: subject:commonName (OID: 2.5.4.3)
    Required/Optional: Deprecated (Discouraged, but not prohibited)
    
    Contents: If present, this field MUST contain a single Domain
    Name(s) owned or controlled by the Subject and to be associated
    with the Subject’s server. Such server MAY be owned and operated
    by the Subject or another entity (e.g., a hosting service).
    Wildcard certificates are not allowed for EV Certificates.
    

    So localhost is fine as long as its a fully qualified domain name. In fact, localhost not even mentioned in the guide.


    Microsoft encourages the practice in KB315588, HOW TO: Secure an ASP.NET Application Using Client-Side Certificates:

    • On the Your Site's Common Name page, type localhost, and then click Next.

    littleblackbox is a database of private SSL/TLS and SSH keys for embedded devices. It comes with a SQlite3 database in bin/.

    The certificates are in PEM format (i.e.,-----BEGIN CERTIFICATE----- and friends). You can dump all the certificates with:

    $ sqlite3 lbb.db 
    SQLite version 3.8.3 2013-12-17 16:32:56
    Enter ".help" for instructions
    Enter SQL statements terminated with a ";"
    sqlite> .mode line
    sqlite> .out certificates.txt
    sqlite> SELECT certificate FROM certificates;
    sqlite> .q
    

    Next, remove the certificate = from the file:

    $ sed -e "s|certificate = ||g" certificates.txt > temp.txt
    $ mv temp.txt certificates.txt
    

    Now use nawk and openssl to decode each certificate:

    nawk '
    v{v=v"\n"$0}
    /----BEGIN/ {v=$0}
    /----END/&&v{
      print v > "tmp.cert"
      close("tmp.cert")
      system("openssl x509 -in tmp.cert -inform PEM -text -noout")
      v=x}' certificates.txt
    

    If we know about them, the bad guys surely know about them.


    Finally, its security posture. With all of that said above, here's why its a bad idea. This is where the security posture comes in. From Peter Gutmann's Engineering Security (p. 45):

    In practice CAs seem to issue certificates under more or less any
    name to pretty much anybody, ranging from small-scale issues like
    users buying certificates for the wonderfully open-ended mail [237]
    through to the six thousand sites that commercial CAs like Comodo,
    Cybertrust, Digicert, Entrust, Equifax, GlobalSign, GoDaddy,
    Microsoft, Starfield and Verisign have certified for localhost,
    with no apparent limit on how many times a CA will issue a
    certificate for the same name [238].
    

    The problem here is, "is it my localhost, or is it your localhost". So its not so much a question of issuing certficate for and trusting your localhost - its more a problem of inadvertently trusting a foreign localhost.

    Once your software (such as a browser) trusts the certificate issued to localhost, its game over.