gnutls CN fallback with unsupported SAN type
hi,
GnuTLS accepts hostnames via Common Name fallback when a certificate contains subjectAltName entries with unsupported types (for example URI), even though RFC 6125 requires CN suppression whenever SAN is present. the issue enables identity verification ambiguity in TLS clients that rely on GnuTLS. equivalent certificates with supported SAN types do not trigger this fallback, so the behavior is dependent on SAN subtype.
Severity
MEDIUM
relevant links
- repo: https://gitlab.com/gnutls/gnutls
- commit: 165ae258
- file: lib/x509/hostname-verify.c:111,245-265
root cause
IS_SAN_SUPPORTED marks only DNS and IP SAN types as supported. URI/other SAN types do not set the have_other_addresses flag, so the CN fallback branch is allowed even when SAN is present. this violates RFC 6125 hostname matching rules for SAN-bearing certificates.
impact
enterprise and controlled PKI deployments can mis-validate server identity if an attacker controls a private CA or a compromised CA path can issue a certificate with URI SAN plus a victim hostname CN. clients using GnuTLS may trust the wrong host under specific certificate profiles.
proof of concept
unzip -q -o poc.zip
bash ./canonical.sh
expected:
[PROOF_MARKER]: gnutls accepts hostname via CN fallback despite URI SAN
unzip -q -o poc.zip
bash ./control.sh
expected:
[NC_MARKER]: certificate with DNS SAN and different CN was correctly rejected by hostname check
expected: with any SAN entry, CN should not decide hostname acceptance actual: unsupported SAN types can trigger CN fallback in GnuTLS a fix accepted when: gnutls suppresses CN fallback whenever a SAN extension is present, regardless of SAN type
attack path
- attacker obtains or controls issuance of a certificate with a SAN URI
- cert is paired with a victim hostname in CN
- GnuTLS client accepts handshake for that hostname
recommended fix
change gnutls_x509_crt_check_hostname2 flow so any SAN presence disables CN fallback unconditionally.
fix accepted when: URI SAN certificates no longer pass hostname check via CN fallback when CN is attacker-controlled
credit: 1seal (https://github.com/1seal)
best, Oleh Konko