Security Audit of Hickory DNS

X41 performed an audit of Hickory DNS which is an open source Rust based DNS client, server, and resolver. We were sponsored by the great folks at OSTIF and supported by Prossimo.

The full report of the security audit can be downloaded under the following link:

Hickory DNS

Hickory DNS is a collection of DNS libraries implementing a DNS authoritative server, client and recursive resolver. The software may be used as part of the DNS distributed database. Vulnerabilities in the application would allow an attacker to disrupt a core service of the Internet by, e.g. by flooding important servers with packets leveraging an amplification attack or hijacking connections of users to important Internet services by poisoning the DNS cache.

Audit Results and Notable Findings

Our security source code audit identified two medium and two low severity security issues. Additionally, seven informational findings were identified. The source code of Hickory DNS was inspected for vulnerabilities by security experts Eric Sesterhenn, Markus Vervier, JM, and Robert Femmer using manual code review and code analysis tools.

The most severe issues identified in this audit allow an attacker to consume all processing, memory or connection resources on the machine running a Hickory DNS recursor or server. This may disrupt Internet service for users as well as enable blind DNS cache poisoning attacks performed against downstream servers, which rely on answers from a Hickory DNS server.

DoS via Open Connections

The code does not set timeouts for TLS or HTTPS connections. Client connections can be kept open for an infinite time, which keeps blocking the client while waiting for an answer.

Additionally, connections against these services to the server can be kept open for an infinite time. Attackers can easily open a huge number of TLS connections and keep them open.

With a large amount of open connections, the daemon will be busy managing mutexes and use all available CPU resources.

This issue has been fixed in commit 2622

Resolver Vulnerable to KeyTrap Attack

Hickory DNS does not limit the number of attempts to verify a signature with a key and hence will suffer from high CPU usage when facing a malicious authority set up with colliding DNSKEY and RRSIG entries.

This is known as the KeyTrap Attack which was described by Heftrig et al. It constitutes a resource exhaustion attack against the DNSSEC verifier of any RFC-compliant DNS resolver. The RFC-compliant resolver must attempt to verify RRSIG records (there may be multiple per record) using DNSKEY records with matching key tag, name class and type. Since the key tag is not collision resistant, multiple DNSKEY records with a matching key tag, name, class, type and differing signatures can be constructed. The complexity of verifying m signatures using n keys is then O(m ⋅ n). Variants of the KeyTrap attack exist, where only one signature is verified against multiple keys, or similar. They are less effective than the KeyTrap attack.

This issue has been fixed in commit 2533

Stack Overflow in Recursor

When an authoritative nameserver that the recursor is querying for some A record returns an empty answer and an NS record in the name servers section, Hickory interprets this as a referral. The referred name server is then resolved and queried for the original A record. The resolver process is started for the referred name server with a recursion depth of zero. Hence, when during the process Hickory is referred to the same name server again, unbounded recursion occurs, which results in a stack overflow, crashing the Hickory resolver.

This issue has been fixed in commit 2522

Out of Memory Denial of Service in Recursor

When the recursor queries upstream servers for records, it may receive a set of CNAME records, which it attempts to resolve. Hickory attempts to resolve all of the records in the set, by using the resolve API. The recursion depth is limited to a configured value, which defaults to 12. When Hickory encounters a malicious server, which replies with c new CNAME records during the recursive resolve, Hickory will attempt to resolve these as well. After n recursion levels, the workload to resolve all CNAME records will be a^n. While the upstream server only has to respond to simple DNS queries, Hickory is also keeping the replies in memory.

When set up as the authority for the test. -zone and queried for any subdomain, e.g. foo.test., it will reply with 40 unique CNAME records in the same zone. When these are resolved, the bogus server will generate another 40 unique records, until the configured recursion depth limit is reached, at which it resolves the query to an A record. At a recursion depth limit of 12 and 40 CNAMEs per request, this will prompt Hickory to resolve and keep in memory the replies for 16777216000000000000 queries.

This issue has been fixed in commit 2531

Conclusion

Hickory DNS’s code base is new and has not seen significant use in a production setting and frequent changes are to be expected in the future. It is recommended to repeat a thorough source code review in due time. Due to the use of Rust, memory safety issues are avoided. However, the code base does not limit the use of system resources sufficiently and DoS conditions can be triggered with low effort. These issues pose only a minor threat to the overall security of the system.

If you are interested in working with us on such projects in the future, remote or in-office, ping us!.