Skip to content

Commit fd56b35

Browse files
committed
Bound DNS-over-HTTPS response read with io.LimitReader
io.ReadAll(resp.Body) in the DoH client reads the full response without a size limit. A malicious or compromised DoH server can send an arbitrarily large response, causing the cert-manager controller to run out of memory. Wrap with io.LimitReader using a 128KB cap, which is well above the DNS over TCP maximum of 65535 bytes (RFC 1035). This matches the existing pattern used in cloudflare.go and http.go for bounding external response reads. Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
1 parent c7fb73f commit fd56b35

1 file changed

Lines changed: 7 additions & 1 deletion

File tree

pkg/issuer/acme/dns/util/wait.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ import (
2424
logf "github.com/cert-manager/cert-manager/pkg/logs"
2525
)
2626

27+
// maxDNSResponseSize is the max size of a received DNS-over-HTTPS response
28+
// body. DNS over TCP responses are limited to 65535 bytes by RFC 1035; this
29+
// is set to a generous 128KB to allow for overhead while still preventing a
30+
// malicious DoH server from sending an arbitrarily large response.
31+
const maxDNSResponseSize = 128 * 1024
32+
2733
type preCheckDNSFunc func(ctx context.Context, fqdn, value string, nameservers []string,
2834
useAuthoritative bool) (bool, error)
2935
type dnsQueryFunc func(ctx context.Context, fqdn string, rtype uint16, nameservers []string, recursive bool) (in *dns.Msg, err error)
@@ -257,7 +263,7 @@ func (c *httpDNSClient) Exchange(ctx context.Context, m *dns.Msg, a string) (r *
257263
return nil, 0, fmt.Errorf("dns: unexpected Content-Type %q; expected %q", ct, dohMimeType)
258264
}
259265

260-
p, err = io.ReadAll(resp.Body)
266+
p, err = io.ReadAll(io.LimitReader(resp.Body, maxDNSResponseSize))
261267
if err != nil {
262268
return nil, 0, err
263269
}

0 commit comments

Comments
 (0)