GHSA-gcjf-9mgh-3p7g Netty: CRLF Injection via Multipart Filename in Netty HttpPostRequestEncoder
Security Vulnerability Report: CRLF Injection via Multipart Filename in Netty HttpPostRequestEncoder1. Vulnerability Summary| Field | Value |
|-------|-------|
| **Product** | Netty |
| **Version** | 4.2.12.Final (and all prior versions with codec-http multipart) |
| **Component** | `io.netty.handler.codec.http.multipart.HttpPostRequestEncoder` |
| **Vulnerability Type** | CWE-93: Improper Neutralization of CRLF Sequences / CWE-113: HTTP Response Splitting |
| **Impact** | MIME Header Injection / Content-Type Spoofing / XSS via Content-Disposition |
| **CVSS 3.1 Score** | **8.1 (High)** |
| **CVSS 3.1 Vector** | `CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N` |
| **Attack Vector** | Network |
| **Attack Complexity** | Low |
| **Privileges Required** | Low (attacker must be able to upload files with controlled filenames) |
| **User Interaction** | None |
| **Scope** | Unchanged |
| **Confidentiality Impact** | High |
| **Integrity Impact** | High |
| **Availability Impact** | None |2. Affected ComponentsThe following classes in the `codec-http` module are affected:`io.netty.handler.codec.http.multipart.HttpPostRequestEncoder` — directly concatenates unvalidated filename/name into `Content-Disposition` MIME headers (lines 519, 633, 674, 682, 686-688)`io.netty.handler.codec.http.multipart.DiskFileUpload` — `setFilename()` only checks null (line 78)`io.netty.handler.codec.http.multipart.MemoryFileUpload` — `setFilename()` only checks null (line 60)`io.netty.handler.codec.http.multipart.MixedFileUpload` — `setFilename()` delegates without validation (line 62)3. Vulnerability DescriptionNetty's `HttpPostRequestEncoder` constructs multipart HTTP request bodies by directly concatenating user-supplied filenames and field names into `Content-Disposition` MIME headers **without validating or sanitizing CRLF characters** (`\r\n`). Since MIME headers are delimited by CRLF, an attacker who controls the filename can inject arbitrary MIME headers into the multipart body part.Root CauseIn `HttpPostRequestEncoder.java`, multiple code paths directly embed `fileUpload.getFilename()` into header strings:The `setFilename()` method in all `FileUpload` implementations only checks for null:Comparison with Similar Fixed CVEsThis vulnerability follows the same pattern as:| CVE | Component | Fix |
|-----|-----------|-----|
| **GHSA-jq43-27x9-3v86** | SmtpRequestEncoder — SMTP command injection | Added CRLF validation in `SmtpUtils.validateSMTPParameters()` |
| **GHSA-84h7-rjj3-6jx4** | HttpRequestEncoder — CRLF in URI | Added `HttpUtil.validateRequestLineTokens()` |The multipart encoder has **no equivalent validation** for filenames or field names.4. Exploitability PrerequisitesThis vulnerability is exploitable when:The application uses Netty's `HttpPostRequestEncoder` to construct multipart HTTP requestsThe filename of an uploaded file is derived from user-controlled inputThe application does **not** perform its own CRLF sanitization on filenames**Common affected patterns**:File upload proxies that forward user-supplied filenamesAPI gateways that construct multipart requests from incoming parametersMicroservice communication that passes filenames between servicesTesting/automation frameworks that use Netty HTTP client with user-defined filenames5. Attack ScenariosScenario 1: Content-Type Override via Filename InjectionAn attacker uploads a file with a crafted filename to override the Content-Type of the multipart body part, potentially enabling stored XSS:**Wire format:**If the receiving server parses the **first** `Content-Type`, the file is treated as HTML instead of JPEG, enabling XSS when the file is served back.Scenario 2: Arbitrary MIME Header InjectionInjects arbitrary headers into the multipart body part that may be processed by downstream middleware or application logic.Scenario 3: Multipart Boundary ConfusionBy injecting a new boundary delimiter, the attacker can:Terminate the current body part prematurelyStart a new body part with a different field nameOverride form fields processed by the server6. Proof of ConceptFull Runnable PoC Source Code (MultipartFilenameInjectionPoC.java)How to Compile and RunPoC Execution Output (Verified on Netty 4.2.12.Final)7. Impact Analysis| Impact Category | Description |
|----------------|-------------|
| **Confidentiality** | HIGH — Injected headers may bypass access controls or leak tokens |
| **Integrity** | HIGH — Content-Type override enables stored XSS; field name injection allows form data manipulation |
| **Content-Type Spoofing** | Override `application/octet-stream` to `text/html` to serve executable content |
| **Stored XSS** | Inject `<script>` tags via Content-Type override when uploaded files are served back |
| **Form Field Override** | Inject new multipart boundaries to create/override form fields |
| **Downstream Injection** | Custom MIME headers may affect middleware, CDN, or storage layer behavior |8. Remediation RecommendationsOption 1: Validate in FileUpload.setFilename() (Recommended)Option 2: Sanitize in HttpPostRequestEncoder (Defense-in-Depth)Escape or reject CRLF characters when building Content-Disposition headers:Option 3: RFC 2231/5987 Encoding for FilenamesUse proper RFC 2231 encoding for filenames with special characters:9. References[RFC 2183: Content-Disposition Header Field](https://tools.ietf.org/html/rfc2183)[RFC 7578: Returning Values from Forms: multipart/form-data](https://tools.ietf.org/html/rfc7578)[RFC 5987: Character Set and Language Encoding for HTTP Header Field Parameters](https://tools.ietf.org/html/rfc5987)[CWE-93: Improper Neutralization of CRLF Sequences](https://cwe.mitre.org/data/definitions/93.html)[CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers](https://cwe.mitre.org/data/definitions/113.html)[GHSA-jq43-27x9-3v86: Netty SMTP Command Injection (same pattern)](https://github.com/netty/netty/security/advisories/GHSA-jq43-27x9-3v86)[GHSA-84h7-rjj3-6jx4: Netty HTTP CRLF Injection (same pattern)](https://github.com/netty/netty/security/advisories/GHSA-84h7-rjj3-6jx4)
CVSS v3.1 score: 5.7