GHSA-cm33-6792-r9fm: Netty has a DNS Codec Input Validation Bypass (Encoder + Decoder)
Security Vulnerability Report: DNS Codec Input Validation Bypass in Netty (Encoder + Decoder)1. Vulnerability Summary| Field | Value |
|-------|-------|
| **Product** | Netty |
| **Version** | 4.2.12.Final (and all prior versions with codec-dns) |
| **Component** | `io.netty.handler.codec.dns.DnsCodecUtil` |
| **Vulnerability Type** | CWE-20: Improper Input Validation / CWE-626: Null Byte Interaction Error / CWE-400: Uncontrolled Resource Consumption |
| **Impact** | DNS Cache Poisoning / Domain Validation Bypass / Denial of Service / Malformed DNS Packets |2. Affected ComponentsBoth the encoder and decoder in the same file are affected:`io.netty.handler.codec.dns.DnsCodecUtil` — `encodeDomainName()` method (lines 31-51):No null byte validation in domain name labelsNo per-label length validation (RFC 1035 max: 63 bytes)No total domain name length validation (RFC 1035 max: 255 bytes)Empty labels silently truncate the domain name`io.netty.handler.codec.dns.DnsCodecUtil` — `decodeDomainName()` method (lines 53-118):No per-label length validation (max 63)No total domain name length validation (max 255)Unbounded StringBuilder growth from attacker-controlled DNS responses3. Vulnerability DescriptionNetty's DNS codec does **not enforce RFC 1035 domain name constraints** during either encoding or decoding. This creates a bidirectional attack surface: malicious DNS responses can exploit the decoder, and user-influenced hostnames can exploit the encoder.3.1 Encoder Side — Null Byte Injection (CWE-626)A domain name containing a null byte (e.g., `"evil\0.example.com"`) is encoded with the null byte embedded in the label data. This creates a domain name that different DNS implementations interpret differently:**Java (full string)**: sees `"evil\0.example.com"` as a single label containing a null**C/native DNS libraries**: truncate at the null byte, seeing only `"evil"`**DNS servers**: may accept or reject based on implementationThis differential interpretation enables **DNS cache poisoning** and **domain validation bypass**.3.2 Encoder Side — Overlength Label (RFC 1035 Violation)Labels exceeding 63 bytes are accepted by the encoder. The length byte is written as a single unsigned byte, so a 200-byte label writes `0xC8` (200) as the length. Per RFC 1035, values 192-255 indicate **compression pointers**. This means:A 200-byte label length `0xC8` would be interpreted as a **compression pointer** by standards-compliant DNS parsersThis creates **parser confusion** between label and pointer interpretation3.3 Encoder Side — Silent Truncation via Empty LabelsAn attacker can craft input like `"safe-domain..evil.com"` which gets truncated to just `"safe-domain."`, potentially bypassing domain allowlists.3.4 Decoder Side — Unbounded Memory AllocationThe decoder accepts labels of any length (0-255 bytes) without checking the RFC 1035 per-label limit of 63 bytes or the total domain name limit of 255 bytes. A malicious DNS server can return responses with oversized labels, causing excessive memory allocation.Root Cause — EncoderRoot Cause — Decoder**Missing checks in decoder**:No `if (len > 63)` check per RFC 1035 Section 2.3.4No `if (name.length() > 255)` check for total domain name length4. Exploitability PrerequisitesEncoder Side (outbound)An application constructs DNS queries using Netty's DNS codec with user-influenced domain namesThe constructed DNS packets are sent to DNS servers or resolversDecoder Side (inbound)An application uses Netty's `codec-dns` or `resolver-dns` module to process DNS responsesThe application communicates with a malicious or compromised DNS server**Attack surface**: Any Netty application using DNS resolution (`DnsNameResolver`) is potentially affected on the decoder side, as DNS responses from the network are attacker-controlled. The encoder side requires user-controlled hostnames.5. Attack ScenariosScenario 1: DNS Cache Poisoning via Null Byte (Encoder)The DNS query for `"evil\0.trusted.com"` may be interpreted by some resolvers as a query for `"evil"` (truncated at null). If the attacker controls the DNS for `"evil"`, they can return a response that gets cached for `"evil\0.trusted.com"` (or vice versa), poisoning the cache.Scenario 2: Label/Pointer Confusion (Encoder)A 200-byte label writes length byte `0xC8`. Standards-compliant parsers interpret `0xC0-0xFF` as **compression pointer** prefixes (RFC 1035 Section 4.1.4). The resulting DNS packet is structurally ambiguous:Scenario 3: Memory Exhaustion via Large Labels (Decoder)A malicious DNS server returns a response with a 255-byte label (RFC limit: 63). Netty decodes it without error, creating a 260+ character String. With compression pointers, a small DNS response can cause megabytes of StringBuilder allocation.Scenario 4: Domain Truncation via Empty Label (Encoder)This can bypass domain allowlists that check the input string.Scenario 5: Downstream Processing Failures (Decoder)Applications that pass decoded domain names to other DNS libraries, certificate validators, or URL parsers may crash or behave incorrectly when receiving names > 255 bytes, as these systems typically assume RFC 1035 compliance.6. Proof of ConceptPoC 1: Encoder Null Byte and Overlength (DnsEncoderNullBytePoC.java)PoC 2: Decoder Length Bypass (DnsDecoderLengthPoC.java)How to Compile and RunPoC Execution Output (Verified on Netty 4.2.12.Final)**Encoder PoC:****Decoder PoC:**7. Impact Analysis| Impact Category | Description |
|----------------|-------------|
| **Integrity** | HIGH — Null byte injection causes differential interpretation across DNS implementations |
| **Availability** | HIGH — Malicious DNS responses can cause unbounded memory allocation via decoder |
| **DNS Cache Poisoning** | Different parsers see different domain names from the same encoded packet |
| **Domain Validation Bypass** | Null bytes can bypass allowlist/blocklist checks in DNS proxies |
| **Label/Pointer Confusion** | Length bytes > 63 conflict with RFC 1035 compression pointer encoding |
| **Silent Truncation** | Empty labels silently drop the remainder of the domain name |
| **Downstream Failures** | Oversized domain names may crash certificate validators, URL parsers, or other DNS-aware libraries |8. Remediation RecommendationsFix for Encoder (encodeDomainName)Fix for Decoder (decodeDomainName)9. Resources[RFC 1035 Section 2.3.4: Size Limits](https://tools.ietf.org/html/rfc1035#section-2.3.4)[RFC 1035 Section 4.1.4: Message Compression](https://tools.ietf.org/html/rfc1035#section-4.1.4)[CWE-20: Improper Input Validation](https://cwe.mitre.org/data/definitions/20.html)[CWE-400: Uncontrolled Resource Consumption](https://cwe.mitre.org/data/definitions/400.html)[CWE-626: Null Byte Interaction Error](https://cwe.mitre.org/data/definitions/626.html)
CVSS v3.1: 7.5