Wildcard SSL Certificates: Does *.example.com Cover Root Domain Without Explicit SAN Entry?


3 views

Many developers assume a wildcard SSL certificate for *.example.com automatically includes coverage for the root domain example.com. While some Certificate Authorities (CAs) may include this by default, RFC 6125 specifically states that wildcard certificates only cover one level of subdomains unless explicitly specified otherwise.

// Example of proper SAN configuration in OpenSSL
openssl req -new -newkey rsa:2048 -nodes -keyout example.key -out example.csr \
  -subj "/CN=*.example.com" \
  -reqexts SAN \
  -config <(cat /etc/ssl/openssl.cnf \
    <(printf "[SAN]\nsubjectAltName=DNS:*.example.com,DNS:example.com"))

Modern browsers follow strict validation rules based on RFC 2818 and RFC 6125. When encountering a wildcard certificate:

  • Chrome 93+ requires exact SAN matches
  • Firefox 91+ follows the "Public Suffix List" rules
  • Safari 15 enforces strict wildcard validation

Let's examine a properly configured certificate using OpenSSL:

openssl x509 -in certificate.crt -text -noout

X509v3 extensions:
    X509v3 Subject Alternative Name: 
        DNS:*.example.com, DNS:example.com

Compare this to the problematic Comodo certificate you received:

X509v3 extensions:
    X509v3 Subject Alternative Name: 
        DNS:*.example.com

Different CAs handle this differently:

CA Includes Root Domain by Default Requires Special Request
DigiCert Yes No
Comodo/Sectigo No Must specify during order
Let's Encrypt No Must use separate -d parameters

For developers needing both coverage:

Option 1: Explicit SAN Request

# When generating CSR:
openssl req -new -sha256 \
    -key domain.key \
    -subj "/CN=*.example.com" \
    -reqexts SAN \
    -config <(printf "[req]\ndistinguished_name=req_distinguished_name\n[SAN]\nsubjectAltName=DNS:example.com,DNS:*.example.com") \
    -out domain.csr

Option 2: ACME Clients (Let's Encrypt)

certbot certonly --manual --preferred-challenges=dns \
    -d example.com \
    -d *.example.com \
    --server https://acme-v02.api.letsencrypt.org/directory

To programmatically verify certificate coverage:

# Python example
import ssl
import socket
from OpenSSL import SSL

def check_cert_coverage(hostname):
    cert = ssl.get_server_certificate((hostname, 443))
    x509 = SSL.load_certificate(SSL.FILETYPE_PEM, cert)
    san = x509.get_extension(2).__str__()
    return 'DNS:'+hostname in san

The technical reality is clear: while some CAs may include root domain coverage as a courtesy, RFC-compliant implementations require explicit SAN entries for both wildcard and root domains to guarantee full coverage across all browsers and clients.


Many developers assume a wildcard certificate for *.example.com automatically secures both subdomains and the root domain. While Comodo claims this should work, real-world implementation often requires explicit SAN entries. Let's examine why.

A properly configured wildcard certificate should include:

Common Name: *.example.com
Subject Alternative Names:
   DNS:*.example.com
   DNS:example.com

When missing the root domain in SANs, browsers like Chrome will flag the root domain as insecure while accepting sub.example.com.

Here's how to properly configure multiple domains with a wildcard cert:

server {
    listen 443 ssl;
    server_name example.com;
    ssl_certificate /path/to/wildcard.crt;
    ssl_certificate_key /path/to/wildcard.key;
    # ... other config
}

server {
    listen 443 ssl;
    server_name *.example.com;
    ssl_certificate /path/to/wildcard.crt;
    ssl_certificate_key /path/to/wildcard.key;
    # ... other config
}

When generating CSR with SANs:

openssl req -new -newkey rsa:2048 -nodes -keyout wildcard.key \
-out wildcard.csr -config san.cnf

Sample san.cnf:

[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req

[req_distinguished_name]
countryName = Country
stateOrProvinceName = State
localityName = City
organizationName = Organization
commonName = *.example.com

[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = *.example.com
DNS.2 = example.com

Check your certificate's SANs with:

openssl x509 -in certificate.crt -text -noout | grep -A 1 "Subject Alternative Name"

For web-based verification, use SSL Labs' tester to confirm coverage.

Different CAs handle wildcards differently:

  • DigiCert: Includes root domain automatically
  • Let's Encrypt: Requires separate certificate
  • Comodo: Mixed reports (case-dependent)

To guarantee coverage for both root and subdomains:

  1. Always request explicit SAN inclusion during CSR generation
  2. Verify certificate contents before deployment
  3. Consider multi-domain certificates if using non-wildcard subdomains
  4. Test all domain variations before production rollout