RFC 4343

Domain Name System (DNS) Case Insensitivity Clarification

πŸ“… published January 2006, from ietf

Domain Name System (DNS) Case Insensitivity Clarification πŸŽ€

Okay bestie, this is RFC 4343 πŸ’– It came from the Network Working Group and was written by D. Eastlake 3rd at Motorola Laboratories. It's dated January 2006 and it's a Standards Track doc, so it's meant to be an actual Internet standard πŸ”₯ It updates RFCs 1034, 1035, and 2181, which is the same list you'll see in the Abstract.


Status of This Memo πŸ“œ

This document specifies an Internet standards track protocol for the Internet community, and it's asking for discussion and suggestions for improvements. For the standardization state and status of this protocol, check the current edition of the "Internet Official Protocol Standards" (STD 1). Distribution of this memo is unlimited ✨

Copyright (C) The Internet Society (2006).

Abstract 🌸

Domain Name System (DNS) names are "case insensitive" πŸ¦‹ This document explains exactly what that means and gives a clear spec of the rules. It also says this clarification updates RFCs 1034, 1035, and 2181.

Table of Contents πŸ—‚οΈ

1. Introduction ....................................................2
2. Case Insensitivity of DNS Labels ................................2
   2.1. Escaping Unusual DNS Label Octets ..........................2
   2.2. Example Labels with Escapes ................................3
3. Name Lookup, Label Types, and CLASS .............................3
   3.1. Original DNS Label Types ...................................4
   3.2. Extended Label Type Case Insensitivity Considerations ......4
   3.3. CLASS Case Insensitivity Considerations ....................4
4. Case on Input and Output ........................................5
   4.1. DNS Output Case Preservation ...............................5
   4.2. DNS Input Case Preservation ................................5
5. Internationalized Domain Names ..................................6
6. Security Considerations .........................................6
7. Acknowledgements ................................................7
Normative References................................................7
Informative References..............................................8

1. Introduction πŸ’…

Okay so, the Domain Name System (DNS) is the global hierarchical replicated distributed database system for Internet addressing, mail proxy, and other information ✨ Every node in the DNS tree has a name made of zero or more labels [STD13, RFC1591, RFC2606], and those labels get treated in a case insensitive fashion. This doc is here to clarify what "case insensitive" actually means for DNS 🫢 This clarification updates RFCs 1034, 1035 [STD13], and [RFC2181].

Here's the deal with the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document: they're read the way [RFC2119] describes πŸ”₯


2. Case Insensitivity of DNS Labels πŸ¦‹

DNS was specified back in the era of [ASCII] πŸ•°οΈ DNS names were expected to look like most host names or Internet email address right halves (the part after the at-sign, "@") or to be numeric, like the in-addr.arpa part of the DNS name space. For example:

    foo.example.net.
    aol.com.
    www.gnu.ai.mit.edu.
or  69.2.0.192.in-addr.arpa.

Case-varied alternatives to the above [RFC3092] would be DNS names like:

    Foo.ExamplE.net.
    AOL.COM.
    WWW.gnu.AI.mit.EDU.
or  69.2.0.192.in-ADDR.ARPA.

But here's the plot twist πŸ™ˆ the individual octets that DNS names are made of are not limited to valid ASCII character codes. They're 8-bit bytes, and all values are allowed. Lots of applications still interpret them as ASCII characters, though.

2.1. Escaping Unusual DNS Label Octets 🌈

In Master Files [STD13] and other human-readable and -writable ASCII contexts, you need an escape for the byte value for period (0x2E, ".") and for all octet values outside the inclusive range from 0x21 ("!") to 0x7E ("~"). That is to say, 0x2E and all octet values in the two inclusive ranges from 0x00 to 0x20 and from 0x7F to 0xFF.

One typographic convention for octets that don't correspond to an ASCII printing graphic is to use a back-slash followed by the value of the octet as an unsigned integer, written as exactly three decimal digits.

The same convention can be used for printing ASCII characters so that they get treated as a normal label character. That includes the back-slash character used in this convention itself, which can be written as \092 or \\, and the special label separator period ("."), which can be written as \046 or \.. It is advisable to avoid using a backslash to quote an immediately following non-printing ASCII character code, to avoid implementation difficulties πŸ™ƒ

A back-slash followed by only one or two decimal digits is undefined πŸ’€ A back-slash followed by four decimal digits produces two octets. The first octet has the value of the first three digits read as a decimal number, and the second octet is the character code for the fourth decimal digit.

2.2. Example Labels with Escapes 🧁

The first example below shows embedded spaces and a period (".") inside a label. The second one shows a 5-octet label where the second octet has all bits zero, the third is a backslash, and the fourth octet has all bits one.

      Donald\032E\.\032Eastlake\0323rd.example.
and   a\000\\\255z.example.

3. Name Lookup, Label Types, and CLASS 🧚

According to the original DNS design decision, comparisons on name lookup for DNS queries should be case insensitive [STD13]. That means a lookup string octet with a value in the inclusive range from 0x41 to 0x5A (the uppercase ASCII letters) MUST match the identical value, and it also MUST match the corresponding value in the inclusive range from 0x61 to 0x7A (the lowercase ASCII letters). A lookup string octet with a lowercase ASCII letter value MUST similarly match the identical value, and also match the corresponding value in the uppercase ASCII letter range. πŸ’œ

(Historical note: the terms "uppercase" and "lowercase" were invented after movable type. They originally referred to the two font trays for storing the different physical type elements, in partitioned areas. Before movable type, the nearest equivalent terms were "majuscule" and "minuscule".) πŸ“š

One way to implement this rule would be to subtract 0x20 from all octets in the inclusive range from 0x61 to 0x7A before comparing octets. This operation is commonly known as "case folding", but implementing it via case folding is not required 🌸 Note that DNS case insensitivity does NOT correspond to the case folding specified in [ISO-8859-1] or [ISO-8859-2]. For example, the octets 0xDD (\221) and 0xFD (\253) do NOT match. In other contexts, where they're read as the upper- and lower-case versions of "Y" with an acute accent, they might match, but not here.

Heads up: 0xDD and 0xFD look like they should match if you're thinking about accented letters, but in DNS they're different octets, so they don't. Don't let your brain autocorrect this one πŸ™ˆ

3.1. Original DNS Label Types πŸŽ€

DNS labels in wire-encoded names have a type associated with them. The original DNS standard [STD13] had only two types. The first is ASCII labels, with a length from zero to 63 octets. The second is indirect (or compression) labels, which are an offset pointer to a name location elsewhere in the wire encoding of a DNS message. (The ASCII label of length zero is reserved for use as the name of the root node of the name tree.) ASCII labels follow the ASCII case conventions described here and, as stated above, can actually contain arbitrary byte values. Indirect labels are, in effect, replaced by the name they point to, and that name is then treated with the case insensitivity rules in this document 🫢

3.2. Extended Label Type Case Insensitivity Considerations πŸ¦‹

DNS was extended by [RFC2671] so that additional label type numbers would be available. The only such type defined so far is the BINARY type [RFC2673], which is now Experimental [RFC3363] πŸ§ͺ

The ASCII case insensitivity conventions only apply to ASCII labels. That is to say, label type 0x0, whether it appears directly or is invoked by indirect labels ✨

3.3. CLASS Case Insensitivity Considerations 🌍

As described in [STD13] and [RFC2929], DNS has an additional axis for data location called CLASS. The only CLASS in global use right now is the "IN" (Internet) CLASS πŸ’–

The handling of DNS label case is not CLASS dependent. With the original design of DNS, it was intended that a recursive DNS resolver be able to handle new CLASSes that were unknown when it was implemented. That requires uniform handling of label case insensitivity. Should it ever become desirable to allocate a CLASS with "case sensitive ASCII labels", it would be necessary to allocate a new label type for those labels πŸ”₯

4.2. DNS Input Case Preservation ✨

Okay so, DNS data originally came from an ASCII Master File as defined in [STD13] or a zone transfer πŸ“„. Then DNS Dynamic update and incremental zone transfers [RFC1995] got added as sources too [RFC2136, RFC3007]. When any of these inputs creates a node in the DNS name tree, no case conversion happens πŸ™…β€β™€οΈ. So the case of ASCII labels is kept for brand new nodes, which is lowkey simple. πŸ’–

It gets messier when a label is input for a node that already exists in the DNS data being held 😭. Implementations are free to keep the case that was loaded first for that label, let new input override the old case, or even keep separate copies that preserve the input case. Choose your fighter πŸ’….

For example, say data with owner name "foo.bar.example" [RFC3092] is loaded, and later data with owner name "xyz.BAR.example" comes in. The label on the "bar.example" node (that's "bar") might or might not get changed to "BAR" in the stored DNS data πŸ€·β€β™€οΈ. So when you retrieve data stored under "xyz.bar.example" later, the answer can use "xyz.BAR.example" everywhere, use "xyz.bar.example" everywhere, or, if more than one RR comes back, mix the two capitalizations. The mixing is pretty unlikely though, because optimizing answer length with indirect labels tends to make just one copy of the name tail ("bar.example" or "BAR.example") get used for every returned RR 🧠. And none of this changes how many RRs come back or whether the RR set is complete. It only changes the case of the names in the RR set πŸŽ€.

The same ideas apply when you input multiple data records whose owner names only differ in case πŸ‘―β€β™€οΈ. Say an "A" record is the first resource record stored under owner name "xyz.BAR.example", and then a second "A" record gets stored under "XYZ.BAR.example". The second record MAY be stored with the first (lower case initial label) name. It MAY override the first so that only an uppercase initial label is kept. Or both capitalizations MAY be kept in the DNS stored data 🌈. Either way, a retrieval with either capitalization will get back all the RRs with either capitalization. No drama 🫢.

One more thing: the order a server database inserts the DNS name tree nodes that show up in a Master File isn't defined πŸ™ˆ. That means inconsistent capitalization in a Master File leads to output capitalization you can't predict. Chaos, but make it make sense πŸ’€.


5. Internationalized Domain Names 🌍

So there's a scheme for "internationalized domain names" and "internationalized labels", described in [RFC3490, RFC3454, RFC3491, and RFC3492] 🧚. It basically makes most of [UNICODE] available through a separate application-level transformation, going from an internationalized domain name to a DNS domain name and back again πŸ¦‹. Any case insensitivity that internationalized domain names and labels have depends on the script, and it's handled entirely as part of the transformation described in [RFC3454] and [RFC3491], which should be seen for further details. This isn't part of the DNS as standardized in STD 13, so don't mix them up, bestie πŸ™…β€β™€οΈ.


6. Security Considerations πŸ”

Okay, this part is serious, so listen up 🚨. The equivalence of certain DNS label types with case differences, as clarified in this document, can lead to security problems 😳. For example, a user could get confused into thinking two domain names that only differ in case are actually different names. Scary stuff 😭.

It gets worse, because a domain name may be used in contexts other than the DNS πŸ’€. It could be used as a case-sensitive index into some database or file system. Or some integrity or authentication code system could interpret it as binary data. These problems can usually be handled by using a standardized or "canonical" form of the DNS ASCII type labels. That means always mapping the ASCII letter value octets in ASCII labels to one specific pre-chosen case, either uppercase or lowercase πŸ”’. An example of a canonical form for domain names (and also a canonical ordering for them) shows up in Section 6 of [RFC4034]. See also [RFC3597] πŸ“š.

Last one! A non-DNS name may get stored into DNS while falsely expecting that case will always be preserved πŸ₯Ί. For example, and yes this would be pretty rare, on a system with case-sensitive email address local parts, trying to store two Responsible Person (RP) [RFC1183] records that only differ in case would probably give unexpected results. Those results might even have security implications 😬. That's because the entire email address, including the possibly case-sensitive local or left-hand part, gets encoded into a DNS name in a readable way. The case of some letters might change on output, like we talked about above πŸ‘€.


7. Acknowledgements 🫢

Huge thanks and lots of love to everyone who contributed to this document: Rob Austein, Olafur Gudmundsson, Daniel J. Anderson, Alan Barrett, Marc Blanchet, Dana, Andreas Gustafsson, Andrew Main, Thomas Narten, and Scott Seligman πŸ’œβœ¨.


Normative References πŸ“–

[ASCII]      ANSI, "USA Standard Code for Information Interchange",
             X3.4, American National Standards Institute: New York,
             1968.

[RFC1995]    Ohta, M., "Incremental Zone Transfer in DNS", RFC 1995,
             August 1996.

[RFC2119]    Bradner, S., "Key words for use in RFCs to Indicate
             Requirement Levels", BCP 14, RFC 2119, March 1997.

[RFC2136]    Vixie, P., Thomson,  S., Rekhter, Y., and J. Bound,
             "Dynamic Updates in the Domain Name System (DNS
             UPDATE)", RFC 2136, April 1997.

[RFC2181]     Elz, R. and R. Bush, "Clarifications to the DNS
             Specification", RFC 2181, July 1997.

[RFC3007]    Wellington, B., "Secure Domain Name System (DNS) Dynamic
             Update", RFC 3007, November 2000.

[RFC3597]    Gustafsson, A., "Handling of Unknown DNS Resource Record
             (RR) Types", RFC 3597, September 2003.

[RFC4034]    Arends, R., Austein, R., Larson, M., Massey, D., and S.
             Rose, "Resource Records for the DNS Security
             Extensions", RFC 4034, March 2005.

[STD13]      Mockapetris, P., "Domain names - concepts and
             facilities", STD 13, RFC 1034, November 1987.

             Mockapetris, P., "Domain names - implementation and
             specification", STD 13, RFC 1035, November 1987.

Informative References πŸ“š

[ISO-8859-1] International Standards Organization, Standard for
             Character Encodings, Latin-1.

[ISO-8859-2] International Standards Organization, Standard for
             Character Encodings, Latin-2.

[RFC1183]    Everhart, C., Mamakos, L., Ullmann, R., and P.
             Mockapetris, "New DNS RR Definitions", RFC 1183, October
             1990.

[RFC1591]    Postel, J., "Domain Name System Structure and
             Delegation", RFC 1591, March 1994.

[RFC2606]    Eastlake 3rd, D. and A. Panitz, "Reserved Top Level DNS
             Names", BCP 32, RFC 2606, June 1999.

[RFC2929]    Eastlake 3rd, D., Brunner-Williams, E., and B. Manning,
             "Domain Name System (DNS) IANA Considerations", BCP 42,
             RFC 2929, September 2000.

[RFC2671]    Vixie, P., "Extension Mechanisms for DNS (EDNS0)", RFC
             2671, August 1999.

[RFC2673]    Crawford, M., "Binary Labels in the Domain Name System",
             RFC 2673, August 1999.

[RFC3092]    Eastlake 3rd, D., Manros, C., and E. Raymond, "Etymology
             of "Foo"", RFC 3092, 1 April 2001.

[RFC3363]    Bush, R., Durand, A., Fink, B., Gudmundsson, O., and T.
             Hain, "Representing Internet Protocol version 6 (IPv6)
             Addresses in the Domain Name System (DNS)", RFC 3363,
             August 2002.

[RFC3454]    Hoffman, P. and M. Blanchet, "Preparation of
             Internationalized Strings ("stringprep")", RFC 3454,
             December 2002.

[RFC3490]    Faltstrom, P., Hoffman, P., and A. Costello,
             "Internationalizing Domain Names in Applications
             (IDNA)", RFC 3490, March 2003.

[RFC3491]    Hoffman, P. and M. Blanchet, "Nameprep: A Stringprep
             Profile for Internationalized Domain Names (IDN)", RFC
             3491, March 2003.

[RFC3492]    Costello, A., "Punycode: A Bootstring encoding of
             Unicode for Internationalized Domain Names in
             Applications (IDNA)", RFC 3492, March 2003.

[UNICODE]    The Unicode Consortium, "The Unicode Standard",
             <http://www.unicode.org/unicode/standard/standard.html>.

Author's Address πŸ–ŠοΈ

Donald E. Eastlake 3rd
Motorola Laboratories
155 Beaver Street
Milford, MA 01757 USA

Phone: +1 508-786-7554 (w)
EMail: Donald.Eastlake@motorola.com

Copyright (C) The Internet Society (2006). πŸ’…

This document is subject to the rights, licenses and restrictions contained in BCP 78. Except as set forth therein, the authors retain all their rights πŸ”.

This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

Intellectual Property 🧠

The IETF takes no position on the validity or scope of any Intellectual Property Rights or other rights that might be claimed to apply to implementing or using the technology described in this document. It also doesn't say whether any license under those rights might or might not be available, and it doesn't claim to have made any independent effort to find such rights πŸ•΅οΈβ€β™€οΈ. Info on the procedures for rights in RFC documents lives in BCP 78 and BCP 79 πŸ“š.

Copies of IPR disclosures made to the IETF Secretariat, any assurances of licenses to be made available, or the results of an attempt to get a general license or permission to use such proprietary rights by implementers or users of this specification can be found in the IETF online IPR repository at http://www.ietf.org/ipr πŸ”—.

The IETF invites any interested party to bring to its attention any copyrights, patents, patent applications, or other proprietary rights that may cover technology required to implement this standard. Send that info to the IETF at ietf-ipr@ietf.org πŸ“¬.


Acknowledgement 🌸

Funding for the RFC Editor function is provided by the IETF Administrative Support Activity (IASA). Thank you, IASA, you're iconic πŸ‘‘βœ¨.

πŸ“¦ where this page comes from