<?xml version='1.0' encoding='utf-8'?>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" version="3" category="info" docName="draft-dashevskyi-dnsrr-antipatterns-06" indexInclude="true" ipr="trust200902" number="9267" prepTime="2022-07-28T06:47:07" scripts="Common,Latin" sortRefs="true" submissionType="independent" symRefs="true" tocDepth="3" tocInclude="true" xml:lang="en">
  <link href="https://datatracker.ietf.org/doc/draft-dashevskyi-dnsrr-antipatterns-06" rel="prev"/>
  <link href="https://dx.doi.org/10.17487/rfc9267" rel="alternate"/>
  <link href="urn:issn:2070-1721" rel="alternate"/>
  <front>
    <title abbrev="Vulnerabilities in DNS RR Processing">Common Implementation Anti-Patterns Related to Domain Name System (DNS) Resource Record (RR) Processing</title>
    <seriesInfo name="RFC" value="9267" stream="independent"/>
    <author initials="S." surname="Dashevskyi" fullname="Stanislav Dashevskyi">
      <organization showOnFrontPage="true">Forescout Technologies</organization>
      <address>
        <postal>
          <street>John F. Kennedylaan, 2</street>
          <city>Eindhoven</city>
          <code>5612AB</code>
          <country>Netherlands</country>
        </postal>
        <email>stanislav.dashevskyi@forescout.com</email>
      </address>
    </author>
    <author initials="D." surname="dos Santos" fullname="Daniel dos Santos">
      <organization showOnFrontPage="true">Forescout Technologies</organization>
      <address>
        <postal>
          <street>John F. Kennedylaan, 2</street>
          <city>Eindhoven</city>
          <code>5612AB</code>
          <country>Netherlands</country>
        </postal>
        <email>daniel.dossantos@forescout.com</email>
      </address>
    </author>
    <author initials="J." surname="Wetzels" fullname="Jos Wetzels">
      <organization showOnFrontPage="true">Forescout Technologies</organization>
      <address>
        <postal>
          <street>John F. Kennedylaan, 2</street>
          <city>Eindhoven</city>
          <code>5612AB</code>
          <country>Netherlands</country>
        </postal>
        <email>jos.wetzels@forescout.com</email>
      </address>
    </author>
    <author initials="A." surname="Amri" fullname="Amine Amri">
      <organization showOnFrontPage="true">Forescout Technologies</organization>
      <address>
        <postal>
          <street>John F. Kennedylaan, 2</street>
          <city>Eindhoven</city>
          <code>5612AB</code>
          <country>Netherlands</country>
        </postal>
        <email>amine.amri@forescout.com</email>
      </address>
    </author>
    <date month="07" year="2022"/>
    <keyword>vulnerabilities</keyword>
    <keyword>vulnerability</keyword>
    <abstract pn="section-abstract">
      <t indent="0" pn="section-abstract-1">
   This memo describes common vulnerabilities related to Domain Name
   System (DNS) resource record (RR) processing as seen in several DNS
   client implementations. These vulnerabilities may lead to successful
   Denial-of-Service and Remote Code Execution attacks against the
   affected software. Where applicable, violations of RFC 1035 are
   mentioned.</t>
    </abstract>
    <boilerplate>
      <section anchor="status-of-memo" numbered="false" removeInRFC="false" toc="exclude" pn="section-boilerplate.1">
        <name slugifiedName="name-status-of-this-memo">Status of This Memo</name>
        <t indent="0" pn="section-boilerplate.1-1">
            This document is not an Internet Standards Track specification; it is
            published for informational purposes.
        </t>
        <t indent="0" pn="section-boilerplate.1-2">
            This is a contribution to the RFC Series, independently of any
            other RFC stream.  The RFC Editor has chosen to publish this
            document at its discretion and makes no statement about its value
            for implementation or deployment.  Documents approved for
            publication by the RFC Editor are not candidates for any level of
            Internet Standard; see Section 2 of RFC 7841.
        </t>
        <t indent="0" pn="section-boilerplate.1-3">
            Information about the current status of this document, any
            errata, and how to provide feedback on it may be obtained at
            <eref target="https://www.rfc-editor.org/info/rfc9267" brackets="none"/>.
        </t>
      </section>
      <section anchor="copyright" numbered="false" removeInRFC="false" toc="exclude" pn="section-boilerplate.2">
        <name slugifiedName="name-copyright-notice">Copyright Notice</name>
        <t indent="0" pn="section-boilerplate.2-1">
            Copyright (c) 2022 IETF Trust and the persons identified as the
            document authors. All rights reserved.
        </t>
        <t indent="0" pn="section-boilerplate.2-2">
            This document is subject to BCP 78 and the IETF Trust's Legal
            Provisions Relating to IETF Documents
            (<eref target="https://trustee.ietf.org/license-info" brackets="none"/>) in effect on the date of
            publication of this document. Please review these documents
            carefully, as they describe your rights and restrictions with
            respect to this document.
        </t>
      </section>
    </boilerplate>
    <toc>
      <section anchor="toc" numbered="false" removeInRFC="false" toc="exclude" pn="section-toc.1">
        <name slugifiedName="name-table-of-contents">Table of Contents</name>
        <ul bare="true" empty="true" indent="2" spacing="compact" pn="section-toc.1-1">
          <li pn="section-toc.1-1.1">
            <t indent="0" keepWithNext="true" pn="section-toc.1-1.1.1"><xref derivedContent="1" format="counter" sectionFormat="of" target="section-1"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-introduction">Introduction</xref></t>
          </li>
          <li pn="section-toc.1-1.2">
            <t indent="0" keepWithNext="true" pn="section-toc.1-1.2.1"><xref derivedContent="2" format="counter" sectionFormat="of" target="section-2"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-compression-pointer-and-off">Compression Pointer and Offset Validation</xref></t>
          </li>
          <li pn="section-toc.1-1.3">
            <t indent="0" keepWithNext="true" pn="section-toc.1-1.3.1"><xref derivedContent="3" format="counter" sectionFormat="of" target="section-3"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-label-and-name-length-valid">Label and Name Length Validation</xref></t>
          </li>
          <li pn="section-toc.1-1.4">
            <t indent="0" pn="section-toc.1-1.4.1"><xref derivedContent="4" format="counter" sectionFormat="of" target="section-4"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-null-terminator-placement-v">Null-Terminator Placement Validation</xref></t>
          </li>
          <li pn="section-toc.1-1.5">
            <t indent="0" pn="section-toc.1-1.5.1"><xref derivedContent="5" format="counter" sectionFormat="of" target="section-5"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-response-data-length-valida">Response Data Length Validation</xref></t>
          </li>
          <li pn="section-toc.1-1.6">
            <t indent="0" pn="section-toc.1-1.6.1"><xref derivedContent="6" format="counter" sectionFormat="of" target="section-6"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-record-count-validation">Record Count Validation</xref></t>
          </li>
          <li pn="section-toc.1-1.7">
            <t indent="0" pn="section-toc.1-1.7.1"><xref derivedContent="7" format="counter" sectionFormat="of" target="section-7"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-security-considerations">Security Considerations</xref></t>
          </li>
          <li pn="section-toc.1-1.8">
            <t indent="0" pn="section-toc.1-1.8.1"><xref derivedContent="8" format="counter" sectionFormat="of" target="section-8"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-iana-considerations">IANA Considerations</xref></t>
          </li>
          <li pn="section-toc.1-1.9">
            <t indent="0" pn="section-toc.1-1.9.1"><xref derivedContent="9" format="counter" sectionFormat="of" target="section-9"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-references">References</xref></t>
            <ul bare="true" empty="true" indent="2" spacing="compact" pn="section-toc.1-1.9.2">
              <li pn="section-toc.1-1.9.2.1">
                <t indent="0" pn="section-toc.1-1.9.2.1.1"><xref derivedContent="9.1" format="counter" sectionFormat="of" target="section-9.1"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-normative-references">Normative References</xref></t>
              </li>
              <li pn="section-toc.1-1.9.2.2">
                <t indent="0" pn="section-toc.1-1.9.2.2.1"><xref derivedContent="9.2" format="counter" sectionFormat="of" target="section-9.2"/>.  <xref derivedContent="" format="title" sectionFormat="of" target="name-informative-references">Informative References</xref></t>
              </li>
            </ul>
          </li>
          <li pn="section-toc.1-1.10">
            <t indent="0" pn="section-toc.1-1.10.1"><xref derivedContent="" format="none" sectionFormat="of" target="section-appendix.a"/><xref derivedContent="" format="title" sectionFormat="of" target="name-acknowledgements">Acknowledgements</xref></t>
          </li>
          <li pn="section-toc.1-1.11">
            <t indent="0" pn="section-toc.1-1.11.1"><xref derivedContent="" format="none" sectionFormat="of" target="section-appendix.b"/><xref derivedContent="" format="title" sectionFormat="of" target="name-authors-addresses">Authors' Addresses</xref></t>
          </li>
        </ul>
      </section>
    </toc>
  </front>
  <middle>
    <section anchor="sect-1" numbered="true" toc="include" removeInRFC="false" pn="section-1">
      <name slugifiedName="name-introduction">Introduction</name>
      <t indent="0" pn="section-1-1">
   Major vulnerabilities in DNS implementations recently became evident and raised attention to this protocol as an important attack vector, as discussed in <xref target="SIGRED" format="default" sectionFormat="of" derivedContent="SIGRED"/>, <xref target="SADDNS" format="default" sectionFormat="of" derivedContent="SADDNS"/>, and
   <xref target="DNSPOOQ" format="default" sectionFormat="of" derivedContent="DNSPOOQ"/>, the latter being a set of 7 critical issues affecting the DNS
   forwarder "dnsmasq".</t>
      <t indent="0" pn="section-1-2">
   The authors of this memo have analyzed the DNS client implementations
   of several major TCP/IP protocol stacks and found a set of
   vulnerabilities that share common implementation flaws
   (anti-patterns). These flaws are related to processing DNS resource records (RRs)
   (discussed in <xref target="RFC1035" format="default" sectionFormat="of" derivedContent="RFC1035"/>) and may lead to critical security
   vulnerabilities.</t>
      <t indent="0" pn="section-1-3">
   While implementation flaws may differ from one software project to
   another, these anti-patterns are highly likely to span
   multiple implementations. In fact, one of the first "Common Vulnerabilities and Exposures" (CVE) documents related to
   one of the anti-patterns <xref target="CVE-2000-0333" format="default" sectionFormat="of" derivedContent="CVE-2000-0333"/> dates back to the year 2000.
   The observations are not limited to DNS client implementations.
   Any software that processes DNS RRs may be affected, such as
   firewalls, intrusion detection systems, or general-purpose DNS packet
   dissectors (e.g., the DNS dissector in Wireshark; see <xref target="CVE-2017-9345" format="default" sectionFormat="of" derivedContent="CVE-2017-9345"/>). Similar issues may
   also occur in DNS-over-HTTPS <xref target="RFC8484" format="default" sectionFormat="of" derivedContent="RFC8484"/> and DNS-over-TLS <xref target="RFC7858" format="default" sectionFormat="of" derivedContent="RFC7858"/>
   implementations. However, any implementation that deals with the DNS
   wire format is subject to the considerations discussed in this document.</t>
      <t indent="0" pn="section-1-4">
   <xref target="I-D.ietf-dnsind-local-compression" format="default" sectionFormat="of" derivedContent="DNS-COMPRESSION"/> and <xref target="RFC5625" format="default" sectionFormat="of" derivedContent="RFC5625"/> briefly mention some of these
   anti-patterns, but the main purpose of this memo is to provide
   technical details behind these anti-patterns, so that the common
   mistakes can be eradicated.</t>
      <t indent="0" pn="section-1-5">
   We provide general recommendations on mitigating the anti-patterns.
   We also suggest that all implementations should drop
   malicious/malformed DNS replies and (optionally) log them.</t>
    </section>
    <section anchor="sect-2" numbered="true" toc="include" removeInRFC="false" pn="section-2">
      <name slugifiedName="name-compression-pointer-and-off">Compression Pointer and Offset Validation</name>
      <t indent="0" pn="section-2-1">
   <xref target="RFC1035" format="default" sectionFormat="of" derivedContent="RFC1035"/> defines the DNS message compression scheme that can be used
   to reduce the size of messages. When it is used, an entire domain
   name or several name labels are replaced with a (compression) pointer
   to a prior occurrence of the same name.</t>
      <t indent="0" pn="section-2-2">
   The compression pointer is a combination of two octets: the two most
   significant bits are set to 1, and the remaining 14 bits are the
   OFFSET field. This field specifies the offset from the beginning of
   the DNS header, at which another domain name or label is located:</t>
      <artwork name="" type="" align="left" alt="" pn="section-2-3">
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| 1  1|                OFFSET                   |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
</artwork>
      <t indent="0" pn="section-2-4">
   The message compression scheme explicitly allows a domain name to be
   represented as one of the following: (1) a sequence of unpacked labels ending with a zero
   octet, (2) a pointer, or (3) a sequence of labels ending with a pointer.</t>
      <t indent="0" pn="section-2-5">
   However, <xref target="RFC1035" format="default" sectionFormat="of" derivedContent="RFC1035"/> does not explicitly state that blindly following
   compression pointers of any kind can be harmful <xref target="I-D.ietf-dnsind-local-compression" format="default" sectionFormat="of" derivedContent="DNS-COMPRESSION"/>, as we
   could not have had any assumptions about various implementations
   that would follow.</t>
      <t indent="0" pn="section-2-6">
   Yet, any DNS packet parser that attempts to decompress domain names
   without validating the value of OFFSET is likely susceptible to
   memory corruption bugs and buffer overruns. These bugs make it easier to perform
   Denial-of-Service attacks and may result in successful Remote Code
   Execution attacks.</t>
      <t indent="0" pn="section-2-7">
   Pseudocode that illustrates a typical example of a broken domain name
   parsing implementation is shown below (<xref target="snippet_1" format="default" sectionFormat="of" derivedContent="Figure 1"/>):</t>
      <figure anchor="snippet_1" align="left" suppress-title="false" pn="figure-1">
        <name slugifiedName="name-a-broken-implementation-of-">A Broken Implementation of a Function That Is Used for Decompressing DNS Domain Names (Pseudocode)</name>
        <sourcecode name="" type="pseudocode" markers="false" pn="section-2-8.1">
 1: decompress_domain_name(*name, *dns_payload) {
 2:
 3:   name_buffer[255];
 4:   copy_offset = 0;
 5:
 6:   label_len_octet = name;
 7:   dest_octet = name_buffer;
 8:
 9:   while (*label_len_octet != 0x00) {
10:
11:      if (is_compression_pointer(*label_len_octet)) {
12:          ptr_offset = get_offset(label_len_octet,
                                        label_len_octet+1);
13:          label_len_octet = dns_payload + ptr_offset + 1;
14:      }
15:
16:      else {
17:          length = *label_len_octet;
18:          copy(dest_octet + copy_offset,
                        label_len_octet+1, *length);
19:
20:         copy_offset += length;
21:          label_len_octet += length + 1;
22:      }
23:
24:   }
25: }
</sourcecode>
      </figure>
      <t indent="0" pn="section-2-9">
   Such implementations typically have a dedicated function for
   decompressing domain names (for example, see <xref target="CVE-2020-24338" format="default" sectionFormat="of" derivedContent="CVE-2020-24338"/> and
   <xref target="CVE-2020-27738" format="default" sectionFormat="of" derivedContent="CVE-2020-27738"/>). Among other parameters, these functions may
   accept a pointer to the beginning of the first name label within an
   RR ("name") and a pointer to the beginning of the DNS payload to be
   used as a starting point for the compression pointer
   ("dns_payload"). The destination buffer for the domain name
   ("name_buffer") is typically limited to 255 bytes as per
   <xref target="RFC1035" format="default" sectionFormat="of" derivedContent="RFC1035"/> and can be allocated either in the stack or in the heap
   memory region.</t>
      <t indent="0" pn="section-2-10">
   The code of the function in <xref target="snippet_1" format="default" sectionFormat="of" derivedContent="Figure 1"/> reads the domain name
   label by label from an RR until it reaches the NUL octet ("0x00") that
   signifies the end of a domain name. If the current label length octet
   ("label_len_octet") is a compression pointer, the code extracts the
   value of the compression offset and uses it to "jump" to another
   label length octet. If the current label length octet is not a
   compression pointer, the label bytes will be copied into the name
   buffer, and the number of bytes copied will correspond to the value
   of the current label length octet. After the copy operation, the code
   will move on to the next label length octet.</t>
      <t indent="0" pn="section-2-11">
   The first issue with this implementation is due to unchecked
   compression offset values. The second issue is due to the absence of
   checks that ensure that a pointer will eventually arrive at a
   decompressed domain label. We describe these issues in more detail
   below.</t>
      <t indent="0" pn="section-2-12">

   <xref target="RFC1035" format="default" sectionFormat="of" derivedContent="RFC1035"/> states that a compression pointer is "a pointer to a prior occurance [sic] of the same name." Also, according to <xref target="RFC1035" format="default" sectionFormat="of" derivedContent="RFC1035"/>,
   the maximum size of DNS packets that can be sent over UDP
   is limited to 512 octets.</t>
      <t indent="0" pn="section-2-13">
   The pseudocode in <xref target="snippet_1" format="default" sectionFormat="of" derivedContent="Figure 1"/>  violates these constraints, as it will
   accept a compression pointer that forces the code to read outside the
   bounds of a DNS packet. For instance, a compression pointer set to
   "0xffff" will produce an offset of 16383 octets, which is most
   definitely pointing to a label length octet somewhere past the bounds of the
   original DNS packet.  Supplying such offset values will most likely
   cause memory corruption issues and may lead to Denial-of-Service
   conditions (e.g., a Null pointer dereference after "label_len_octet"
   is set to an invalid address in memory). For additional examples,
   see <xref target="CVE-2020-25767" format="default" sectionFormat="of" derivedContent="CVE-2020-25767"/>, <xref target="CVE-2020-24339" format="default" sectionFormat="of" derivedContent="CVE-2020-24339"/>, and <xref target="CVE-2020-24335" format="default" sectionFormat="of" derivedContent="CVE-2020-24335"/>.</t>
      <t indent="0" pn="section-2-14">
   The pseudocode in <xref target="snippet_1" format="default" sectionFormat="of" derivedContent="Figure 1"/> allows jumping from a compression
   pointer to another compression pointer and does not restrict the
   number of such jumps. That is, if a label length octet that is
   currently being parsed is a compression pointer, the code will
   perform a jump to another label, and if that other label is a
   compression pointer as well, the code will perform another jump, and
   so forth until it reaches a decompressed label. This may lead to
   unforeseen side effects that result in security issues.</t>
      <t indent="0" pn="section-2-15">Consider the DNS packet excerpt illustrated below:</t>
      <artwork name="" type="" align="left" alt="" pn="section-2-16">
        +----+----+----+----+----+----+----+----+----+----+----+----+
  +0x00 |    ID   |  FLAGS  | QDCOUNT | ANCOUNT | NSCOUNT | ARCOUNT |
        +----+----+----+----+----+----+----+----+----+----+----+----+
-&gt;+0x0c |0xc0|0x0c|   TYPE  |  CLASS  |0x04| t  | e  | s  | t  |0x03|
|       +----+--|-+----+----+----+----+----+----+----+----+----+----+
| +0x18 | c  | o| | m  |0x00|  TYPE   |  CLASS  | ................  |
|       +----+--|-+----+----+----+----+----+----+----+----+----+----+
|               |
-----------------
</artwork>
      <t indent="0" pn="section-2-17">
   The packet begins with a DNS header at offset +0x00, and its DNS
   payload contains several RRs. The first RR begins at an offset of
   12 octets (+0x0c); its first label length octet is set to the
   value "0xc0", which indicates that it is a compression pointer. The
   compression pointer offset is computed from the two octets "0xc00c"
   and is equal to 12. Since the broken implementation in <xref target="snippet_1" format="default" sectionFormat="of" derivedContent="Figure 1"/>
   follows this offset value blindly, the pointer will jump back to
   the first octet of the first RR (+0x0c) over and over again.  The
   code in <xref target="snippet_1" format="default" sectionFormat="of" derivedContent="Figure 1"/> will enter an infinite-loop state, since it will
   never leave the "TRUE" branch of the "while" loop.</t>
      <t indent="0" pn="section-2-18">
   Apart from achieving infinite loops, the implementation flaws in
   <xref target="snippet_1" format="default" sectionFormat="of" derivedContent="Figure 1"/> make it possible to achieve various pointer loops that have
   other undesirable effects. For instance, consider the DNS packet excerpt shown
   below:</t>
      <artwork name="" type="" align="left" alt="" pn="section-2-19">
        +----+----+----+----+----+----+----+----+----+----+----+----+
  +0x00 |    ID   |  FLAGS  | QDCOUNT | ANCOUNT | NSCOUNT | ARCOUNT |
        +----+----+----+----+----+----+----+----+----+----+----+----+
-&gt;+0x0c |0x04| t  | e  | s  | t  |0xc0|0x0c| ...................... |
|       +----+----+----+----+----+----+--|-+----+----+----+----+----+
|                                        |
------------------------------------------
</artwork>
      <t indent="0" pn="section-2-20">
   With such a domain name, the implementation in <xref target="snippet_1" format="default" sectionFormat="of" derivedContent="Figure 1"/> will first
   copy the domain label at offset "0xc0" ("test"); it will then 
   fetch the next label length octet, which happens to be a compression pointer
   ("0xc0"). The compression pointer offset is computed from the two
   octets "0xc00c" and is equal to 12 octets. The code will jump back
   to offset "0xc0" where the first label "test" is located. The
   code will again copy the "test" label and then jump back to it,
   following the compression pointer, over and over again.</t>
      <t indent="0" pn="section-2-21">
   <xref target="snippet_1" format="default" sectionFormat="of" derivedContent="Figure 1"/> does not contain any logic that restricts multiple jumps
   from the same compression pointer and does not ensure that no more
   than 255 octets are copied into the name buffer ("name_buffer"). In
   fact,</t>
      <ul spacing="normal" bare="false" empty="false" indent="3" pn="section-2-22">
        <li pn="section-2-22.1">the code will continue to write the label "test" into it,
   overwriting the name buffer and the stack of the heap metadata.</li>
        <li pn="section-2-22.2">attackers would have a significant degree of freedom in
   constructing shell code, since they can create arbitrary copy chains
   with various combinations of labels and compression pointers.</li>
      </ul>
      <t indent="0" pn="section-2-23">Therefore, blindly following compression pointers may lead not only to
   Denial-of-Service conditions, as pointed out by <xref target="I-D.ietf-dnsind-local-compression" format="default" sectionFormat="of" derivedContent="DNS-COMPRESSION"/>, but also to successful Remote
   Code Execution attacks, as there may be other implementation issues present
   within the corresponding code.</t>
      <t indent="0" pn="section-2-24">
   Some implementations may not follow <xref target="RFC1035" format="default" sectionFormat="of" derivedContent="RFC1035"/>, which states:

      </t>
      <blockquote pn="section-2-25">The first two bits are ones.  This allows a pointer to be distinguished
from a label, since the label must begin with two zero bits because
labels are restricted to 63 octets or less.  (The 10 and 01 combinations
are reserved for future use.)</blockquote>
      <t indent="0" pn="section-2-26">
Figures <xref target="snippet_2" format="counter" sectionFormat="of" derivedContent="2"/> and <xref target="snippet_3" format="counter" sectionFormat="of" derivedContent="3"/> show pseudocode that implements two functions that check whether a given octet is a compression pointer; <xref target="snippet_2" format="default" sectionFormat="of" derivedContent="Figure 2"/> shows a correct implementation, and <xref target="snippet_3" format="default" sectionFormat="of" derivedContent="Figure 3"/> shows an incorrect (broken) implementation.</t>
      <figure anchor="snippet_2" align="left" suppress-title="false" pn="figure-2">
        <name slugifiedName="name-correct-compression-pointer">Correct Compression Pointer Check</name>
        <sourcecode name="" type="pseudocode" markers="false" pn="section-2-27.1">
1: unsigned char is_compression_pointer(*octet) {
2:     if ((*octet &amp; 0xc0) == 0xc0)
3:         return true;
4:     } else {
5:         return false;
6:     }
7: }
</sourcecode>
      </figure>
      <figure anchor="snippet_3" align="left" suppress-title="false" pn="figure-3">
        <name slugifiedName="name-broken-compression-pointer-">Broken Compression Pointer Check</name>
        <sourcecode name="" type="pseudocode" markers="false" pn="section-2-28.1">
1: unsigned char is_compression_pointer(*octet) {
2:     if (*octet &amp; 0xc0) {
3:         return true;
4:     } else {
5:         return false;
6:     }
7: }
</sourcecode>
      </figure>
      <t indent="0" pn="section-2-29">
The correct implementation (<xref target="snippet_2" format="default" sectionFormat="of" derivedContent="Figure 2"/>) ensures that the two most
significant bits of an octet are both set, while the broken
implementation (<xref target="snippet_3" format="default" sectionFormat="of" derivedContent="Figure 3"/>) would consider an octet with only one of
the two bits set to be a compression pointer. This is likely an
implementation mistake rather than an intended violation of
<xref target="RFC1035" format="default" sectionFormat="of" derivedContent="RFC1035"/>, because there are no benefits in supporting such
compression pointer values. The implementations related to
<xref target="CVE-2020-24338" format="default" sectionFormat="of" derivedContent="CVE-2020-24338"/> and <xref target="CVE-2020-24335" format="default" sectionFormat="of" derivedContent="CVE-2020-24335"/> had a broken
compression pointer check, similar to the code shown in <xref target="snippet_3" format="default" sectionFormat="of" derivedContent="Figure 3"/>.</t>
      <t indent="0" pn="section-2-30">
   While incorrect implementations alone do not lead to vulnerabilities,
   they may have unforeseen side effects when combined with other
   vulnerabilities. For instance, the first octet of the value "0x4130"
   may be incorrectly interpreted as a label length by a broken
   implementation. Such a label length (65) is invalid and is larger
   than 63 (as per <xref target="RFC1035" format="default" sectionFormat="of" derivedContent="RFC1035"/>); a packet that has this value should
   be discarded. However, the function shown in <xref target="snippet_3" format="default" sectionFormat="of" derivedContent="Figure 3"/> will
   consider "0x41" to be a valid compression pointer, and the packet
   may pass the validation steps.</t>
      <t indent="0" pn="section-2-31">
   This might give attackers additional leverage for constructing
   payloads and circumventing the existing DNS packet validation
   mechanisms.</t>
      <t indent="0" pn="section-2-32">
   The first occurrence of a compression pointer in an RR (an octet with
   the two highest bits set to 1) must resolve to an octet within a DNS
   record with a value that is greater than 0 (i.e., it must not be a
   Null-terminator) and less than 64. The offset at which this octet is
   located must be smaller than the offset at which the compression
   pointer is located; once an implementation makes sure of that,
   compression pointer loops can never occur.</t>
      <t indent="0" pn="section-2-33">
   In small DNS implementations (e.g., embedded TCP/IP stacks),
   support for nested compression pointers (pointers that point to a
   compressed name) should be discouraged: there is very little to be
   gained in terms of performance versus the high probability of
   introducing errors such as those discussed above.</t>
      <t indent="0" pn="section-2-34">
   The code that implements domain name parsing should check the offset
   with respect to not only the bounds of a packet but also its
   position with respect to the compression pointer in question. A
   compression pointer must not be "followed" more than once. We have
   seen several implementations using a check that ensures that
   a compression pointer is not followed more than several times. A
   better alternative may be to ensure that the target of a compression
   pointer is always located before the location of the pointer in the
   packet.</t>
    </section>
    <section anchor="sect-3" numbered="true" toc="include" removeInRFC="false" pn="section-3">
      <name slugifiedName="name-label-and-name-length-valid">Label and Name Length Validation</name>
      <t indent="0" pn="section-3-1">
   <xref target="RFC1035" format="default" sectionFormat="of" derivedContent="RFC1035"/> restricts the length of name labels to 63 octets and
   lengths of domain names to 255 octets (i.e., label octets and label
   length octets). Some implementations do not explicitly enforce these
   restrictions.</t>
      <t indent="0" pn="section-3-2">
   Consider the function "copy_domain_name()" shown in <xref target="snippet_4" format="default" sectionFormat="of" derivedContent="Figure 4"/> below.
   The function is a variant of the "decompress_domain_name()" function
   (<xref target="snippet_1" format="default" sectionFormat="of" derivedContent="Figure 1"/>), with the difference that it does not support compressed
   labels and only copies decompressed labels into the name buffer.</t>
      <figure anchor="snippet_4" align="left" suppress-title="false" pn="figure-4">
        <name slugifiedName="name-a-broken-implementation-of-a">A Broken Implementation of a Function That Is Used for Copying Non-⁠compressed Domain Names</name>
        <sourcecode name="" type="pseudocode" markers="false" pn="section-3-3.1">
 1: copy_domain_name(*name, *dns_payload) {
 2:
 3:   name_buffer[255];
 4:   copy_offset = 0;
 5:
 6:   label_len_octet = name;
 7:   dest_octet = name_buffer;
 8:
 9:   while (*label_len_octet != 0x00) {
10:
11:      if (is_compression_pointer(*label_len_octet)) {
12:          length = 2;
13:          label_len_octet += length + 1;
14:      }
15:
16:      else {
17:          length = *label_len_octet;
18:          copy(dest_octet + copy_offset,
                             label_len_octet+1, *length);
19:
20:         copy_offset += length;
21:          label_len_octet += length + 1;
22:      }
23:
24:  }
25: }
</sourcecode>
      </figure>
      <t indent="0" pn="section-3-4">
   This implementation does not explicitly check for the value of the
   label length octet: this value can be up to 255 octets, and a single
   label can fill the name buffer. Depending on the memory layout of the
   target, how the name buffer is allocated, and the size of the
   malformed packet, it is possible to trigger various memory corruption
   issues.</t>
      <t indent="0" pn="section-3-5">
   Both Figures <xref target="snippet_1" format="counter" sectionFormat="of" derivedContent="1"/> and <xref target="snippet_4" format="counter" sectionFormat="of" derivedContent="4"/> restrict the size of the name buffer to 255
   octets; however, there are no restrictions on the actual number of
   octets that will be copied into this buffer. In this particular case,
   a subsequent copy operation (if another label is present in the
   packet) will write past the name buffer, allowing heap
   or stack metadata to be overwritten in a controlled manner.</t>
      <t indent="0" pn="section-3-6">
   Similar examples of vulnerable implementations can be found in the
   code relevant to <xref target="CVE-2020-25110" format="default" sectionFormat="of" derivedContent="CVE-2020-25110"/>, <xref target="CVE-2020-15795" format="default" sectionFormat="of" derivedContent="CVE-2020-15795"/>, and
   <xref target="CVE-2020-27009" format="default" sectionFormat="of" derivedContent="CVE-2020-27009"/>.</t>
      <t indent="0" pn="section-3-7">
   As a general recommendation, a domain label length octet must have a
   value of more than 0 and less than 64 <xref target="RFC1035" format="default" sectionFormat="of" derivedContent="RFC1035"/>. If this is not the case,
   an invalid value has been provided within the packet, or a value at an
   invalid position might be interpreted as a domain name length due to other
   errors in the packet (e.g., misplaced Null-terminator or invalid
   compression pointer).</t>
      <t indent="0" pn="section-3-8">
   The number of domain label characters must correspond to the value of
   the domain label octet. To avoid possible errors when interpreting
   the characters of a domain label, developers may consider
   recommendations for the preferred domain name syntax outlined in
   <xref target="RFC1035" format="default" sectionFormat="of" derivedContent="RFC1035"/>.</t>
      <t indent="0" pn="section-3-9">
   The domain name length must not be more than 255 octets, including
   the size of decompressed domain names. The NUL octet ("0x00") must
   be present at the end of the domain name and must be within the maximum name
   length (255 octets).</t>
    </section>
    <section anchor="sect-4" numbered="true" toc="include" removeInRFC="false" pn="section-4">
      <name slugifiedName="name-null-terminator-placement-v">Null-Terminator Placement Validation</name>
      <t indent="0" pn="section-4-1">
   A domain name must end with a NUL ("0x00") octet, as per <xref target="RFC1035" format="default" sectionFormat="of" derivedContent="RFC1035"/>.
   The implementations shown in Figures <xref target="snippet_1" format="counter" sectionFormat="of" derivedContent="1"/> and <xref target="snippet_4" format="counter" sectionFormat="of" derivedContent="4"/> assume that this is the
   case for the RRs that they process; however, names that do not have a
   NUL octet placed at the proper position within an RR are not
   discarded.</t>
      <t indent="0" pn="section-4-2">
   This issue is closely related to the absence of label and name length
   checks. For example, the logic behind Figures <xref target="snippet_1" format="counter" sectionFormat="of" derivedContent="1"/> and <xref target="snippet_4" format="counter" sectionFormat="of" derivedContent="4"/> will continue
   to copy octets into the name buffer until a NUL octet is
   encountered. This octet can be placed at an arbitrary position
   within an RR or not placed at all.</t>
      <t indent="0" pn="section-4-3">
   Consider the pseudocode function shown in <xref target="snippet_5" format="default" sectionFormat="of" derivedContent="Figure 5"/>. The function
   returns the length of a domain name ("name") in octets to be used
   elsewhere (e.g., to allocate a name buffer of a certain size): for
   compressed domain names, the function returns 2; for decompressed
   names, it returns their true length using the "strlen(3)" function.</t>
      <figure anchor="snippet_5" align="left" suppress-title="false" pn="figure-5">
        <name slugifiedName="name-a-broken-implementation-of-a-">A Broken Implementation of a Function That Returns the Length of a Domain Name</name>
        <sourcecode name="" type="pseudocode" markers="false" pn="section-4-4.1">
1: get_name_length(*name) {
2:
3:     if (is_compression_pointer(name))
4:         return 2;
5:
6:     name_len = strlen(name) + 1;
7:     return name_len;
8: }
</sourcecode>
      </figure>
      <t indent="0" pn="section-4-5">
   "strlen(3)" is a standard C library function that returns the length
   of a given sequence of characters terminated by the NUL ("0x00")
   octet. Since this function also expects names to be explicitly
   Null-terminated, the return value "strlen(3)" may also be controlled
   by attackers. Through the value of "name_len", attackers may control
   the allocation of internal buffers or specify the number by octets
   copied into these buffers, or they may perform other operations, depending on the
   implementation specifics.</t>
      <t indent="0" pn="section-4-6">
   The absence of explicit checks for placement of the NUL octet may also
   facilitate controlled memory reads and writes. An example of
   vulnerable implementations can be found in the code relevant to
   <xref target="CVE-2020-25107" format="default" sectionFormat="of" derivedContent="CVE-2020-25107"/>, <xref target="CVE-2020-17440" format="default" sectionFormat="of" derivedContent="CVE-2020-17440"/>, <xref target="CVE-2020-24383" format="default" sectionFormat="of" derivedContent="CVE-2020-24383"/>, and
   <xref target="CVE-2020-27736" format="default" sectionFormat="of" derivedContent="CVE-2020-27736"/>.</t>
      <t indent="0" pn="section-4-7">
   As a general recommendation for mitigating such issues, developers
   should never trust user data to be Null-terminated. For example, to
   fix/mitigate the issue shown in the code in <xref target="snippet_5" format="default" sectionFormat="of" derivedContent="Figure 5"/>, developers should use
   the function "strnlen(3)", which reads at most X characters (the second
   argument of the function), and ensure that X is not larger than the
   buffer allocated for the name.</t>
    </section>
    <section anchor="sect-5" numbered="true" toc="include" removeInRFC="false" pn="section-5">
      <name slugifiedName="name-response-data-length-valida">Response Data Length Validation</name>
      <t indent="0" pn="section-5-1">
   As stated in <xref target="RFC1035" format="default" sectionFormat="of" derivedContent="RFC1035"/>, every RR contains a variable-length string of
   octets that contains the retrieved resource data (RDATA) (e.g., an IP
   address that corresponds to a domain name in question). The length of
   the RDATA field is regulated by the resource data length field
   (RDLENGTH), which is also present in an RR.</t>
      <t indent="0" pn="section-5-2">
   Implementations that process RRs may not check for the validity of
   the RDLENGTH field value when retrieving RDATA. Failing to do so may
   lead to out-of-bound read issues, whose impact may
   vary significantly, depending on the implementation specifics. We have
   observed instances of Denial-of-Service conditions and information
   leaks.</t>
      <t indent="0" pn="section-5-3">
   Therefore, the value of the data length byte in response DNS records
   (RDLENGTH) must reflect the number of bytes available in the field
   that describes the resource (RDATA). The format of RDATA must
   conform to the TYPE and CLASS fields of the RR.</t>
      <t indent="0" pn="section-5-4">
   Examples of vulnerable implementations can be found in the code
   relevant to <xref target="CVE-2020-25108" format="default" sectionFormat="of" derivedContent="CVE-2020-25108"/>, <xref target="CVE-2020-24336" format="default" sectionFormat="of" derivedContent="CVE-2020-24336"/>, and <xref target="CVE-2020-27009" format="default" sectionFormat="of" derivedContent="CVE-2020-27009"/>.</t>
    </section>
    <section anchor="sect-6" numbered="true" toc="include" removeInRFC="false" pn="section-6">
      <name slugifiedName="name-record-count-validation">Record Count Validation</name>
      <t indent="0" pn="section-6-1">
   According to <xref target="RFC1035" format="default" sectionFormat="of" derivedContent="RFC1035"/>, the DNS header contains four two-octet
   fields that specify the amount of question records (QDCOUNT), answer
   records (ANCOUNT), authority records (NSCOUNT), and additional
   records (ARCOUNT).</t>
      <t indent="0" pn="section-6-2">
   <xref target="snippet_6" format="default" sectionFormat="of" derivedContent="Figure 6"/> illustrates a recurring implementation anti-pattern for a
   function that processes DNS RRs. The function "process_dns_records()"
   extracts the value of ANCOUNT ("num_answers") and the pointer to the
   DNS data payload ("data_ptr"). The function processes answer records
   in a loop, decrementing the "num_answers" value after processing each
   record until the value of "num_answers" becomes zero. For
   simplicity, we assume that there is only one domain name per answer.
   Inside the loop, the code calculates the domain name length
   ("name_length") and adjusts the data payload pointer ("data_ptr") by the
   offset that corresponds to "name_length + 1", so that the pointer
   lands on the first answer record. Next, the answer record is
   retrieved and processed, and the "num_answers" value is decremented.</t>
      <figure anchor="snippet_6" align="left" suppress-title="false" pn="figure-6">
        <name slugifiedName="name-a-broken-implementation-of-a-f">A Broken Implementation of a Function That Processes RRs</name>
        <sourcecode name="" type="pseudocode" markers="false" pn="section-6-3.1">
 1: process_dns_records(dns_header, ...) {
        // ...
 2:     num_answers = dns_header-&gt;ancount
 3:     data_ptr = dns_header-&gt;data
 4:
 5:     while (num_answers &gt; 0) {
 6:         name_length = get_name_length(data_ptr);
 7:         data_ptr += name_length + 1;
 8:
 9:         answer = (struct dns_answer_record *)data_ptr;
10:
11:         // process the answer record
12:
13:         --num_answers;
14:     }
        // ...
15: }
</sourcecode>
      </figure>
      <t indent="0" pn="section-6-4">
   If the ANCOUNT number retrieved from the header
   ("dns_header-&gt;ancount") is not checked against the amount of data
   available in the packet and it is, for example, larger than the number of
   answer records available, the data pointer ("data_ptr") will read outside
   the bounds of the packet.  This may result in Denial-of-Service
   conditions.</t>
      <t indent="0" pn="section-6-5">
   In this section, we used an example of processing answer records.
   However, the same logic is often reused for implementing the
   processing of other types of records, e.g., the number of question
   (QDCOUNT), authority (NSCOUNT), and additional (ARCOUNT) records. The
   specified numbers of these records must correspond to the actual data
   present within the packet. Therefore, all record count fields must
   be checked before fully parsing the contents of a packet.
   Specifically, <xref target="RFC5625" sectionFormat="of" section="6.3" format="default" derivedLink="https://rfc-editor.org/rfc/rfc5625#section-6.3" derivedContent="RFC5625"/> recommends that such malformed
   DNS packets should be dropped and (optionally) logged.</t>
      <t indent="0" pn="section-6-6">
   Examples of vulnerable implementations can be found in the code
   relevant to <xref target="CVE-2020-25109" format="default" sectionFormat="of" derivedContent="CVE-2020-25109"/>, <xref target="CVE-2020-24340" format="default" sectionFormat="of" derivedContent="CVE-2020-24340"/>, <xref target="CVE-2020-24334" format="default" sectionFormat="of" derivedContent="CVE-2020-24334"/>, and
   <xref target="CVE-2020-27737" format="default" sectionFormat="of" derivedContent="CVE-2020-27737"/>.</t>
    </section>
    <section anchor="sect-7" numbered="true" toc="include" removeInRFC="false" pn="section-7">
      <name slugifiedName="name-security-considerations">Security Considerations</name>
      <t indent="0" pn="section-7-1">
   Security issues are discussed throughout this memo; it
   discusses implementation flaws (anti-patterns) that affect the
   functionality of processing DNS RRs. The presence of such
   anti-patterns leads to bugs that cause buffer overflows,
   read-out-of-bounds, and infinite-loop issues. These issues have the
   following security impacts: information leaks, Denial-of-Service attacks, and
   Remote Code Execution attacks.</t>
      <t indent="0" pn="section-7-2">
   This document lists general recommendations for the developers of DNS
   record parsing functionality that allow those developers to prevent such
   implementation flaws, e.g., by rigorously checking the data received
   over the wire before processing it.</t>
    </section>
    <section anchor="sect-8" numbered="true" toc="include" removeInRFC="false" pn="section-8">
      <name slugifiedName="name-iana-considerations">IANA Considerations</name>
      <t indent="0" pn="section-8-1">
   This document has no IANA actions. Please see
   <xref target="RFC6895" format="default" sectionFormat="of" derivedContent="RFC6895"/> for a complete review of the IANA considerations
   introduced by DNS.</t>
    </section>
  </middle>
  <back>
    <displayreference target="I-D.ietf-dnsind-local-compression" to="DNS-COMPRESSION"/>
    <references pn="section-9">
      <name slugifiedName="name-references">References</name>
      <references pn="section-9.1">
        <name slugifiedName="name-normative-references">Normative References</name>
        <reference anchor="RFC1035" target="https://www.rfc-editor.org/info/rfc1035" quoteTitle="true" derivedAnchor="RFC1035">
          <front>
            <title>Domain names - implementation and specification</title>
            <author initials="P.V." surname="Mockapetris" fullname="P.V. Mockapetris">
              <organization showOnFrontPage="true"/>
            </author>
            <date year="1987" month="November"/>
            <abstract>
              <t indent="0">This RFC is the revised specification of the protocol and format used in the implementation of the Domain Name System.  It obsoletes RFC-883. This memo documents the details of the domain name client - server communication.</t>
            </abstract>
          </front>
          <seriesInfo name="STD" value="13"/>
          <seriesInfo name="RFC" value="1035"/>
          <seriesInfo name="DOI" value="10.17487/RFC1035"/>
        </reference>
        <reference anchor="RFC5625" target="https://www.rfc-editor.org/info/rfc5625" quoteTitle="true" derivedAnchor="RFC5625">
          <front>
            <title>DNS Proxy Implementation Guidelines</title>
            <author initials="R." surname="Bellis" fullname="R. Bellis">
              <organization showOnFrontPage="true"/>
            </author>
            <date year="2009" month="August"/>
            <abstract>
              <t indent="0">This document provides guidelines for the implementation of DNS proxies, as found in broadband gateways and other similar network devices.  This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="152"/>
          <seriesInfo name="RFC" value="5625"/>
          <seriesInfo name="DOI" value="10.17487/RFC5625"/>
        </reference>
      </references>
      <references pn="section-9.2">
        <name slugifiedName="name-informative-references">Informative References</name>
        <reference anchor="CVE-2000-0333" target="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2000-0333" quoteTitle="true" derivedAnchor="CVE-2000-0333">
          <front>
            <title>CVE-2000-0333: A denial-of-service vulnerability in tcpdump, Ethereal, and other sniffer packages via malformed DNS packets</title>
            <author>
              <organization showOnFrontPage="true">Common Vulnerabilities and Exposures</organization>
            </author>
            <date year="2000"/>
          </front>
        </reference>
        <reference anchor="CVE-2017-9345" target="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9345" quoteTitle="true" derivedAnchor="CVE-2017-9345">
          <front>
            <title>CVE-2017-9345: An infinite loop in the DNS dissector of Wireshark</title>
            <author>
              <organization showOnFrontPage="true">Common Vulnerabilities and Exposures</organization>
            </author>
            <date year="2017"/>
          </front>
        </reference>
        <reference anchor="CVE-2020-15795" target="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-15795" quoteTitle="true" derivedAnchor="CVE-2020-15795">
          <front>
            <title>CVE-2020-15795: A denial-of-service and remote code execution vulnerability DNS domain name label parsing functionality of Nucleus NET</title>
            <author>
              <organization showOnFrontPage="true">Common Vulnerabilities and Exposures</organization>
            </author>
            <date year="2021"/>
          </front>
        </reference>
        <reference anchor="CVE-2020-17440" target="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-17440" quoteTitle="true" derivedAnchor="CVE-2020-17440">
          <front>
            <title>CVE-2020-17440 A denial-of-service vulnerability in the DNS name parsing implementation of uIP</title>
            <author>
              <organization showOnFrontPage="true">Common Vulnerabilities and Exposures</organization>
            </author>
            <date year="2020"/>
          </front>
        </reference>
        <reference anchor="CVE-2020-24334" target="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-24334" quoteTitle="true" derivedAnchor="CVE-2020-24334">
          <front>
            <title>CVE-2020-24334: An out-of-bounds read and denial-of-service vulnerability in the DNS response parsing functionality of uIP</title>
            <author>
              <organization showOnFrontPage="true">Common Vulnerabilities and Exposures</organization>
            </author>
            <date year="2020"/>
          </front>
        </reference>
        <reference anchor="CVE-2020-24335" target="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-24335" quoteTitle="true" derivedAnchor="CVE-2020-24335">
          <front>
            <title>CVE-2020-24335: A memory corruption vulnerability in domain name parsing routines of uIP</title>
            <author>
              <organization showOnFrontPage="true">Common Vulnerabilities and Exposures</organization>
            </author>
            <date year="2020"/>
          </front>
        </reference>
        <reference anchor="CVE-2020-24336" target="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-24336" quoteTitle="true" derivedAnchor="CVE-2020-24336">
          <front>
            <title>CVE-2020-24336: A buffer overflow vulnerability in the DNS implementation of Contiki and Contiki-NG</title>
            <author>
              <organization showOnFrontPage="true">Common Vulnerabilities and Exposures</organization>
            </author>
            <date year="2020"/>
          </front>
        </reference>
        <reference anchor="CVE-2020-24338" target="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-24338" quoteTitle="true" derivedAnchor="CVE-2020-24338">
          <front>
            <title>CVE-2020-24338: A denial-of-service and remote code execution vulnerability in the DNS domain name record decompression functionality of picoTCP</title>
            <author>
              <organization showOnFrontPage="true">Common Vulnerabilities and Exposures</organization>
            </author>
            <date year="2020"/>
          </front>
        </reference>
        <reference anchor="CVE-2020-24339" target="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-24339" quoteTitle="true" derivedAnchor="CVE-2020-24339">
          <front>
            <title>CVE-2020-24339: An out-of-bounds read and denial-of-service vulnerability in the DNS domain name record decompression functionality of picoTCP</title>
            <author>
              <organization showOnFrontPage="true">Common Vulnerabilities and Exposures</organization>
            </author>
            <date year="2020"/>
          </front>
        </reference>
        <reference anchor="CVE-2020-24340" target="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-24340" quoteTitle="true" derivedAnchor="CVE-2020-24340">
          <front>
            <title>CVE-2020-24340: An out-of-bounds read and denial-of-service vulnerability in the DNS response parsing functionality of picoTCP</title>
            <author>
              <organization showOnFrontPage="true">Common Vulnerabilities and Exposures</organization>
            </author>
            <date year="2020"/>
          </front>
        </reference>
        <reference anchor="CVE-2020-24383" target="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-24383" quoteTitle="true" derivedAnchor="CVE-2020-24383">
          <front>
            <title>CVE-2020-24383: An information leak and denial-of-service vulnerability while parsing mDNS resource records in FNET</title>
            <author>
              <organization showOnFrontPage="true">Common Vulnerabilities and Exposures</organization>
            </author>
            <date year="2020"/>
          </front>
        </reference>
        <reference anchor="CVE-2020-25107" target="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-25107" quoteTitle="true" derivedAnchor="CVE-2020-25107">
          <front>
            <title>CVE-2020-25107: A denial-of-service and remote code execution vulnerability in the DNS implementation of Ethernut Nut/OS</title>
            <author>
              <organization showOnFrontPage="true">Common Vulnerabilities and Exposures</organization>
            </author>
            <date year="2020"/>
          </front>
        </reference>
        <reference anchor="CVE-2020-25108" target="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-25108" quoteTitle="true" derivedAnchor="CVE-2020-25108">
          <front>
            <title>CVE-2020-25108: A denial-of-service and remote code execution vulnerability in the DNS implementation of Ethernut Nut/OS</title>
            <author>
              <organization showOnFrontPage="true">Common Vulnerabilities and Exposures</organization>
            </author>
            <date year="2020"/>
          </front>
        </reference>
        <reference anchor="CVE-2020-25109" target="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-25109" quoteTitle="true" derivedAnchor="CVE-2020-25109">
          <front>
            <title>CVE-2020-25109: A denial-of-service and remote code execution vulnerability in the DNS implementation of Ethernut Nut/OS</title>
            <author>
              <organization showOnFrontPage="true">Common Vulnerabilities and Exposures</organization>
            </author>
            <date year="2020"/>
          </front>
        </reference>
        <reference anchor="CVE-2020-25110" target="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-25110" quoteTitle="true" derivedAnchor="CVE-2020-25110">
          <front>
            <title>CVE-2020-25110: A denial-of-service and remote code execution vulnerability in the DNS implementation of Ethernut Nut/OS</title>
            <author>
              <organization showOnFrontPage="true">Common Vulnerabilities and Exposures</organization>
            </author>
            <date year="2020"/>
          </front>
        </reference>
        <reference anchor="CVE-2020-25767" target="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-25767" quoteTitle="true" derivedAnchor="CVE-2020-25767">
          <front>
            <title>CVE-2020-25767: An out-of-bounds read and denial-of-service vulnerability in the DNS name parsing routine of HCC Embedded NicheStack</title>
            <author>
              <organization showOnFrontPage="true">Common Vulnerabilities and Exposures</organization>
            </author>
            <date year="2021"/>
          </front>
        </reference>
        <reference anchor="CVE-2020-27009" target="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-27009" quoteTitle="true" derivedAnchor="CVE-2020-27009">
          <front>
            <title>CVE-2020-27009: A denial-of-service and remote code execution vulnerability DNS domain name record decompression functionality of Nucleus NET</title>
            <author>
              <organization showOnFrontPage="true">Common Vulnerabilities and Exposures</organization>
            </author>
            <date year="2021"/>
          </front>
        </reference>
        <reference anchor="CVE-2020-27736" target="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-27736" quoteTitle="true" derivedAnchor="CVE-2020-27736">
          <front>
            <title>CVE-2020-27736: An information leak and denial-of-service vulnerability in the DNS name parsing functionality of Nucleus NET</title>
            <author>
              <organization showOnFrontPage="true">Common Vulnerabilities and Exposures</organization>
            </author>
            <date year="2021"/>
          </front>
        </reference>
        <reference anchor="CVE-2020-27737" target="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-27737" quoteTitle="true" derivedAnchor="CVE-2020-27737">
          <front>
            <title>CVE-2020-27737: An information leak and denial-of-service vulnerability in the DNS response parsing functionality of Nucleus NET</title>
            <author>
              <organization showOnFrontPage="true">Common Vulnerabilities and Exposures</organization>
            </author>
            <date year="2021"/>
          </front>
        </reference>
        <reference anchor="CVE-2020-27738" target="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-27738" quoteTitle="true" derivedAnchor="CVE-2020-27738">
          <front>
            <title>CVE-2020-27738: A denial-of-service and remote code execution vulnerability DNS domain name record decompression functionality of Nucleus NET</title>
            <author>
              <organization showOnFrontPage="true">Common Vulnerabilities and Exposures</organization>
            </author>
            <date year="2021"/>
          </front>
        </reference>
        <reference anchor="I-D.ietf-dnsind-local-compression" quoteTitle="true" target="https://datatracker.ietf.org/doc/html/draft-ietf-dnsind-local-compression-05" derivedAnchor="DNS-COMPRESSION">
          <front>
            <title>A New Scheme for the Compression of Domain Names</title>
            <author initials="P." surname="Koch" fullname="Peter Koch">
              <organization showOnFrontPage="true">Universitaet Bielefeld</organization>
            </author>
            <date month="June" day="30" year="1999"/>
            <abstract>
              <t indent="0">The compression of domain names in DNS messages was introduced in
[RFC1035].  Although some remarks were made about applicability to
future defined resource record types, no method has been deployed yet
to support interoperable DNS compression for RR types specified since
then.
              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-dnsind-local-compression-05"/>
          <format type="TXT" target="https://www.ietf.org/archive/id/draft-ietf-dnsind-local-compression-05.txt"/>
          <refcontent>Work in Progress</refcontent>
        </reference>
        <reference anchor="DNSPOOQ" target="https://www.jsof-tech.com/wp-content/uploads/2021/01/DNSpooq-Technical-WP.pdf" quoteTitle="true" derivedAnchor="DNSPOOQ">
          <front>
            <title>DNSpooq: Cache Poisoning and RCE in Popular DNS Forwarder dnsmasq</title>
            <author initials="M." surname="Kol" fullname="Moshe Kol">
              <organization showOnFrontPage="true"/>
            </author>
            <author initials="S." surname="Oberman" fullname="Shlomi Oberman">
              <organization showOnFrontPage="true"/>
            </author>
            <date month="January" year="2021"/>
          </front>
          <refcontent>JSOF Technical Report</refcontent>
        </reference>
        <reference anchor="RFC6895" target="https://www.rfc-editor.org/info/rfc6895" quoteTitle="true" derivedAnchor="RFC6895">
          <front>
            <title>Domain Name System (DNS) IANA Considerations</title>
            <author initials="D." surname="Eastlake 3rd" fullname="D. Eastlake 3rd">
              <organization showOnFrontPage="true"/>
            </author>
            <date year="2013" month="April"/>
            <abstract>
              <t indent="0">This document specifies Internet Assigned Numbers Authority (IANA) parameter assignment considerations for the allocation of Domain Name System (DNS) resource record types, CLASSes, operation codes, error codes, DNS protocol message header bits, and AFSDB resource record subtypes.  It obsoletes RFC 6195 and updates RFCs 1183, 2845, 2930, and 3597.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="42"/>
          <seriesInfo name="RFC" value="6895"/>
          <seriesInfo name="DOI" value="10.17487/RFC6895"/>
        </reference>
        <reference anchor="RFC7858" target="https://www.rfc-editor.org/info/rfc7858" quoteTitle="true" derivedAnchor="RFC7858">
          <front>
            <title>Specification for DNS over Transport Layer Security (TLS)</title>
            <author initials="Z." surname="Hu" fullname="Z. Hu">
              <organization showOnFrontPage="true"/>
            </author>
            <author initials="L." surname="Zhu" fullname="L. Zhu">
              <organization showOnFrontPage="true"/>
            </author>
            <author initials="J." surname="Heidemann" fullname="J. Heidemann">
              <organization showOnFrontPage="true"/>
            </author>
            <author initials="A." surname="Mankin" fullname="A. Mankin">
              <organization showOnFrontPage="true"/>
            </author>
            <author initials="D." surname="Wessels" fullname="D. Wessels">
              <organization showOnFrontPage="true"/>
            </author>
            <author initials="P." surname="Hoffman" fullname="P. Hoffman">
              <organization showOnFrontPage="true"/>
            </author>
            <date year="2016" month="May"/>
            <abstract>
              <t indent="0">This document describes the use of Transport Layer Security (TLS) to provide privacy for DNS.  Encryption provided by TLS eliminates opportunities for eavesdropping and on-path tampering with DNS queries in the network, such as discussed in RFC 7626.  In addition, this document specifies two usage profiles for DNS over TLS and provides advice on performance considerations to minimize overhead from using TCP and TLS with DNS.</t>
              <t indent="0">This document focuses on securing stub-to-recursive traffic, as per the charter of the DPRIVE Working Group.  It does not prevent future applications of the protocol to recursive-to-authoritative traffic.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="7858"/>
          <seriesInfo name="DOI" value="10.17487/RFC7858"/>
        </reference>
        <reference anchor="RFC8484" target="https://www.rfc-editor.org/info/rfc8484" quoteTitle="true" derivedAnchor="RFC8484">
          <front>
            <title>DNS Queries over HTTPS (DoH)</title>
            <author initials="P." surname="Hoffman" fullname="P. Hoffman">
              <organization showOnFrontPage="true"/>
            </author>
            <author initials="P." surname="McManus" fullname="P. McManus">
              <organization showOnFrontPage="true"/>
            </author>
            <date year="2018" month="October"/>
            <abstract>
              <t indent="0">This document defines a protocol for sending DNS queries and getting DNS responses over HTTPS.  Each DNS query-response pair is mapped into an HTTP exchange.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8484"/>
          <seriesInfo name="DOI" value="10.17487/RFC8484"/>
        </reference>
        <reference anchor="SADDNS" target="https://dl.acm.org/doi/pdf/10.1145/3372297.3417280" quoteTitle="true" derivedAnchor="SADDNS">
          <front>
            <title>DNS Cache Poisoning Attack Reloaded: Revolutions with Side Channels</title>
            <author initials="K." surname="Man" fullname="Keyu Man">
              <organization showOnFrontPage="true"/>
            </author>
            <author initials="Z." surname="Qian" fullname="Zhiyun Qian">
              <organization showOnFrontPage="true"/>
            </author>
            <author initials="Z." surname="Wang" fullname="Zhongjie Wang">
              <organization showOnFrontPage="true"/>
            </author>
            <author initials="X." surname="Zheng" fullname="Xiaofeng Zheng">
              <organization showOnFrontPage="true"/>
            </author>
            <author initials="Y." surname="Huang" fullname="Youjun Huang">
              <organization showOnFrontPage="true"/>
            </author>
            <author initials="H." surname="Duan" fullname="Haixin Duan">
              <organization showOnFrontPage="true"/>
            </author>
            <date month="November" year="2020"/>
          </front>
          <refcontent>Proc. 2020 ACM SIGSAC Conference on Computer and Communications Security, CCS '20</refcontent>
          <seriesInfo name="DOI" value="10.1145/3372297.3417280"/>
        </reference>
        <reference anchor="SIGRED" target="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1350" quoteTitle="true" derivedAnchor="SIGRED">
          <front>
            <title>CVE-2020-1350: A remote code execution vulnerability in Windows Domain Name System servers</title>
            <author>
              <organization showOnFrontPage="true">Common Vulnerabilities and Exposures</organization>
            </author>
            <date year="2020"/>
          </front>
        </reference>
      </references>
    </references>
    <section numbered="false" anchor="acknowledgements" toc="include" removeInRFC="false" pn="section-appendix.a">
      <name slugifiedName="name-acknowledgements">Acknowledgements</name>
      <t indent="0" pn="section-appendix.a-1">
   We would like to thank <contact fullname="Shlomi Oberman"/>, who has greatly contributed to
   the research that led to the creation of this document.</t>
    </section>
    <section anchor="authors-addresses" numbered="false" removeInRFC="false" toc="include" pn="section-appendix.b">
      <name slugifiedName="name-authors-addresses">Authors' Addresses</name>
      <author initials="S." surname="Dashevskyi" fullname="Stanislav Dashevskyi">
        <organization showOnFrontPage="true">Forescout Technologies</organization>
        <address>
          <postal>
            <street>John F. Kennedylaan, 2</street>
            <city>Eindhoven</city>
            <code>5612AB</code>
            <country>Netherlands</country>
          </postal>
          <email>stanislav.dashevskyi@forescout.com</email>
        </address>
      </author>
      <author initials="D." surname="dos Santos" fullname="Daniel dos Santos">
        <organization showOnFrontPage="true">Forescout Technologies</organization>
        <address>
          <postal>
            <street>John F. Kennedylaan, 2</street>
            <city>Eindhoven</city>
            <code>5612AB</code>
            <country>Netherlands</country>
          </postal>
          <email>daniel.dossantos@forescout.com</email>
        </address>
      </author>
      <author initials="J." surname="Wetzels" fullname="Jos Wetzels">
        <organization showOnFrontPage="true">Forescout Technologies</organization>
        <address>
          <postal>
            <street>John F. Kennedylaan, 2</street>
            <city>Eindhoven</city>
            <code>5612AB</code>
            <country>Netherlands</country>
          </postal>
          <email>jos.wetzels@forescout.com</email>
        </address>
      </author>
      <author initials="A." surname="Amri" fullname="Amine Amri">
        <organization showOnFrontPage="true">Forescout Technologies</organization>
        <address>
          <postal>
            <street>John F. Kennedylaan, 2</street>
            <city>Eindhoven</city>
            <code>5612AB</code>
            <country>Netherlands</country>
          </postal>
          <email>amine.amri@forescout.com</email>
        </address>
      </author>
    </section>
  </back>
</rfc>
