Only replace DNS label with placeholder if it's utterly unparsable
e.g. contains control characters, Punycode conversion fails There are quite simply too many certs with bogus DNS labels out in the wild, and it just doesn't make sense to bother every .com domain holder because GoDaddy signed a cert with a DNS name like "www. just4funpartyrentals.com" It is highly unlikely any validator will ever match that DNS name.
This commit is contained in:
parent
60636ba2d7
commit
ea3db97486
|
@ -58,14 +58,15 @@ func setWatchDomains (domains []string) error {
|
||||||
// For example, if we're monitoring sub.example.com, also monitor:
|
// For example, if we're monitoring sub.example.com, also monitor:
|
||||||
// *.example.com
|
// *.example.com
|
||||||
// ?.example.com
|
// ?.example.com
|
||||||
// <invalid>.example.com
|
// <unparsable>.example.com
|
||||||
|
// TODO: support for wildcards that are not the entire label (e.g. ac-*.fr)
|
||||||
var parentDomain string
|
var parentDomain string
|
||||||
if dot := strings.IndexRune(asciiDomain, '.'); dot != -1 {
|
if dot := strings.IndexRune(asciiDomain, '.'); dot != -1 {
|
||||||
parentDomain = asciiDomain[dot:]
|
parentDomain = asciiDomain[dot:]
|
||||||
}
|
}
|
||||||
addWatchDomain("*" + parentDomain)
|
addWatchDomain("*" + parentDomain)
|
||||||
addWatchDomain("?" + parentDomain)
|
addWatchDomain("?" + parentDomain)
|
||||||
addWatchDomain(ctwatch.InvalidDNSLabelPlaceholder + parentDomain)
|
addWatchDomain(ctwatch.UnparsableDNSLabelPlaceholder + parentDomain)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"golang.org/x/net/idna"
|
"golang.org/x/net/idna"
|
||||||
)
|
)
|
||||||
|
|
||||||
const InvalidDNSLabelPlaceholder = "<invalid>"
|
const UnparsableDNSLabelPlaceholder = "<unparsable>"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
const (
|
const (
|
||||||
|
@ -61,25 +61,14 @@ func latin1ToUTF8 (value []byte) string {
|
||||||
return string(runes)
|
return string(runes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate a DNS label. We are less strict than we could be,
|
// Make sure the DNS label doesn't have any weird characters that
|
||||||
// because the main purpose of this is to prevent nasty characters
|
// could cause trouble during later processing.
|
||||||
// from getting through that could cause headaches later (e.g. NUL,
|
func isSaneDNSLabelChar (ch rune) bool {
|
||||||
// control characters). In particular, we allow '_' (since it's
|
return ch == '\t' || (ch >= 32 && ch <= 126)
|
||||||
// quite common in hostnames despite being prohibited), '*' (since
|
|
||||||
// it's used to represent wildcards), and '?' (since it's used
|
|
||||||
// in CT to represent redacted labels).
|
|
||||||
func isValidDNSLabelChar (ch rune) bool {
|
|
||||||
return (ch >= 'A' && ch <= 'Z') ||
|
|
||||||
(ch >= 'a' && ch <= 'z') ||
|
|
||||||
(ch >= '0' && ch <= '9') ||
|
|
||||||
ch == '-' || ch == '_';
|
|
||||||
}
|
}
|
||||||
func isValidDNSLabel (label string) bool {
|
func isSaneDNSLabel (label string) bool {
|
||||||
if label == "*" || label == "?" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
for _, ch := range label {
|
for _, ch := range label {
|
||||||
if !isValidDNSLabelChar(ch) {
|
if !isSaneDNSLabelChar(ch) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,13 +103,17 @@ func trimTrailingDots (value string) string {
|
||||||
return value[0:length]
|
return value[0:length]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert the DNS name to lower case and replace invalid labels with a placeholder
|
// Try to canonicalize/sanitize the DNS name:
|
||||||
|
// 1. Trim leading and trailing whitespace
|
||||||
|
// 2. Trim trailing dots
|
||||||
|
// 3. Convert to lower case
|
||||||
|
// 4. Replace totally nonsensical labels (e.g. having non-printable characters) with a placeholder
|
||||||
func sanitizeDNSName (value string) string {
|
func sanitizeDNSName (value string) string {
|
||||||
value = strings.ToLower(trimTrailingDots(strings.TrimSpace(value)))
|
value = strings.ToLower(trimTrailingDots(strings.TrimSpace(value)))
|
||||||
labels := strings.Split(value, ".")
|
labels := strings.Split(value, ".")
|
||||||
for i, label := range labels {
|
for i, label := range labels {
|
||||||
if !isValidDNSLabel(label) {
|
if !isSaneDNSLabel(label) {
|
||||||
labels[i] = InvalidDNSLabelPlaceholder
|
labels[i] = UnparsableDNSLabelPlaceholder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return strings.Join(labels, ".")
|
return strings.Join(labels, ".")
|
||||||
|
@ -131,10 +124,10 @@ func sanitizeUnicodeDNSName (value string) string {
|
||||||
value = strings.ToLower(trimTrailingDots(strings.TrimSpace(value)))
|
value = strings.ToLower(trimTrailingDots(strings.TrimSpace(value)))
|
||||||
labels := strings.Split(value, ".")
|
labels := strings.Split(value, ".")
|
||||||
for i, label := range labels {
|
for i, label := range labels {
|
||||||
if asciiLabel, err := idna.ToASCII(label); err == nil && isValidDNSLabel(asciiLabel) {
|
if asciiLabel, err := idna.ToASCII(label); err == nil && isSaneDNSLabel(asciiLabel) {
|
||||||
labels[i] = asciiLabel
|
labels[i] = asciiLabel
|
||||||
} else {
|
} else {
|
||||||
labels[i] = InvalidDNSLabelPlaceholder
|
labels[i] = UnparsableDNSLabelPlaceholder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return strings.Join(labels, ".")
|
return strings.Join(labels, ".")
|
||||||
|
|
Loading…
Reference in New Issue