CVE-2026-27145
Description
(*x509.Certificate).VerifyHostname previously called matchHostnames in a loop over all DNS Subject Alternative Name (SAN) entries. This caused strings.Split(host, ".") to execute repeatedly on the same input hostname. With a large DNS SAN list, verification costs scaled quadratically based on the number of SAN entries multiplied by the hostname's label count. Because x509.Verify validates hostnames before building the certificate chain, this overhead occurred even for untrusted certificates.
Patches
1d01955d5d50ccrypto/x509: split candidate hostname only once
1 file changed · +9 −6
src/crypto/x509/verify.go+9 −6 modified@@ -110,7 +110,7 @@ func (h HostnameError) Error() string { c := h.Certificate maxNamesIncluded := 100 - if !c.hasSANExtension() && matchHostnames(c.Subject.CommonName, h.Host) { + if !c.hasSANExtension() && matchHostnames(c.Subject.CommonName, splitHostname(h.Host)) { return "x509: certificate relies on legacy Common Name field, use SANs instead" } @@ -872,16 +872,14 @@ func matchExactly(hostA, hostB string) bool { return toLowerCaseASCII(hostA) == toLowerCaseASCII(hostB) } -func matchHostnames(pattern, host string) bool { +func matchHostnames(pattern string, hostParts []string) bool { pattern = toLowerCaseASCII(pattern) - host = toLowerCaseASCII(strings.TrimSuffix(host, ".")) - if len(pattern) == 0 || len(host) == 0 { + if len(pattern) == 0 || len(hostParts) == 0 { return false } patternParts := strings.Split(pattern, ".") - hostParts := strings.Split(host, ".") if len(patternParts) != len(hostParts) { return false @@ -959,6 +957,7 @@ func (c *Certificate) VerifyHostname(h string) error { candidateName := toLowerCaseASCII(h) // Save allocations inside the loop. validCandidateName := validHostnameInput(candidateName) + hostParts := splitHostname(candidateName) for _, match := range c.DNSNames { // Ideally, we'd only match valid hostnames according to RFC 6125 like @@ -967,7 +966,7 @@ func (c *Certificate) VerifyHostname(h string) error { // always allow perfect matches, and only apply wildcard and trailing // dot processing to valid hostnames. if validCandidateName && validHostnamePattern(match) { - if matchHostnames(match, candidateName) { + if matchHostnames(match, hostParts) { return nil } } else { @@ -980,6 +979,10 @@ func (c *Certificate) VerifyHostname(h string) error { return HostnameError{c, h} } +func splitHostname(host string) []string { + return strings.Split(toLowerCaseASCII(strings.TrimSuffix(host, ".")), ".") +} + func checkChainForKeyUsage(chain []*Certificate, keyUsages []ExtKeyUsage) bool { usages := make([]ExtKeyUsage, len(keyUsages)) copy(usages, keyUsages)
Vulnerability mechanics
Root cause
"The `matchHostnames` function was repeatedly called within a loop, leading to quadratic performance scaling."
Attack vector
An attacker can trigger this vulnerability by providing a certificate with a large number of DNS Subject Alternative Name (SAN) entries. The `(*x509.Certificate).VerifyHostname` function, which is called during hostname verification, iterates through these SANs. This verification occurs even for untrusted certificates before the certificate chain is built, making it susceptible to performance degradation.
Affected code
The vulnerability exists in the `(*x509.Certificate).VerifyHostname` function within the `src/crypto/x509/verify.go` file. Specifically, the `matchHostnames` function was called repeatedly inside a loop over DNS SAN entries, causing `strings.Split(host, '.')` to execute multiple times on the same input [patch_id=4549445].
What the fix does
The patch modifies the `(*x509.Certificate).VerifyHostname` function to call `splitHostname` only once before the loop that iterates over SAN entries. The `matchHostnames` function is then updated to accept the pre-split hostname parts. This change ensures that the hostname is split into its constituent parts only once, preventing redundant computations and resolving the quadratic performance scaling issue [patch_id=4549445].
Generated on Jun 2, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4News mentions
0No linked articles in our index yet.