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:
|
||||
// *.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
|
||||
if dot := strings.IndexRune(asciiDomain, '.'); dot != -1 {
|
||||
parentDomain = asciiDomain[dot:]
|
||||
}
|
||||
addWatchDomain("*" + parentDomain)
|
||||
addWatchDomain("?" + parentDomain)
|
||||
addWatchDomain(ctwatch.InvalidDNSLabelPlaceholder + parentDomain)
|
||||
addWatchDomain(ctwatch.UnparsableDNSLabelPlaceholder + parentDomain)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"golang.org/x/net/idna"
|
||||
)
|
||||
|
||||
const InvalidDNSLabelPlaceholder = "<invalid>"
|
||||
const UnparsableDNSLabelPlaceholder = "<unparsable>"
|
||||
|
||||
/*
|
||||
const (
|
||||
|
@ -61,25 +61,14 @@ func latin1ToUTF8 (value []byte) string {
|
|||
return string(runes)
|
||||
}
|
||||
|
||||
// Validate a DNS label. We are less strict than we could be,
|
||||
// because the main purpose of this is to prevent nasty characters
|
||||
// from getting through that could cause headaches later (e.g. NUL,
|
||||
// control characters). In particular, we allow '_' (since it's
|
||||
// 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 == '_';
|
||||
// Make sure the DNS label doesn't have any weird characters that
|
||||
// could cause trouble during later processing.
|
||||
func isSaneDNSLabelChar (ch rune) bool {
|
||||
return ch == '\t' || (ch >= 32 && ch <= 126)
|
||||
}
|
||||
func isValidDNSLabel (label string) bool {
|
||||
if label == "*" || label == "?" {
|
||||
return true
|
||||
}
|
||||
func isSaneDNSLabel (label string) bool {
|
||||
for _, ch := range label {
|
||||
if !isValidDNSLabelChar(ch) {
|
||||
if !isSaneDNSLabelChar(ch) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -114,13 +103,17 @@ func trimTrailingDots (value string) string {
|
|||
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 {
|
||||
value = strings.ToLower(trimTrailingDots(strings.TrimSpace(value)))
|
||||
labels := strings.Split(value, ".")
|
||||
for i, label := range labels {
|
||||
if !isValidDNSLabel(label) {
|
||||
labels[i] = InvalidDNSLabelPlaceholder
|
||||
if !isSaneDNSLabel(label) {
|
||||
labels[i] = UnparsableDNSLabelPlaceholder
|
||||
}
|
||||
}
|
||||
return strings.Join(labels, ".")
|
||||
|
@ -131,10 +124,10 @@ func sanitizeUnicodeDNSName (value string) string {
|
|||
value = strings.ToLower(trimTrailingDots(strings.TrimSpace(value)))
|
||||
labels := strings.Split(value, ".")
|
||||
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
|
||||
} else {
|
||||
labels[i] = InvalidDNSLabelPlaceholder
|
||||
labels[i] = UnparsableDNSLabelPlaceholder
|
||||
}
|
||||
}
|
||||
return strings.Join(labels, ".")
|
||||
|
|
Loading…
Reference in New Issue