GitHub Security Advisory: GHSA-cm33-6792-r9fm
Package: io.netty:netty-codec-dns (MAVEN)
Severity: HIGH (CVSS 7.5)
CWE: CWE-20: Improper Input Validation, CWE-400: Uncontrolled Resource Consumption, CWE-626: Null Byte Interaction Error (Poison Null Byte)
Vulnerable versions: >= 4.2.0.Alpha1, <= 4.2.12.Final
Patched in: 4.2.13.Final

Summary: Netty has a DNS Codec Input Validation Bypass (Encoder + Decoder)

Details:
# 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 Components

Both 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 labels
  - No 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 responses

## 3. Vulnerability Description

Netty'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 implementation

This 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 parsers
- This creates **parser confusion** between label and pointer interpretation

### 3.3 Encoder Side — Silent Truncation via Empty Labels

```java
encodeDomainName("a..b.com", buf);
// Encodes as: [01] 'a' [00]
// Only "a." is encoded, ".b.com" is silently dropped!
```

An attacker can craft input like `"safe-domain..evil.com"` which gets truncated to just `"safe-domain."`, potentially bypassing domain allowlists.

### 3.4 Decoder Side — Unbo