Apr 2, 2026·6 min read·60 visits
Rack's multipart parser fails to strip CRLF sequences from folded headers, allowing attackers to inject new HTTP headers if the application reflects parsed multipart metadata.
The Rack modular Ruby web server interface contains an Improper Neutralization of CRLF Sequences vulnerability in its `Rack::Multipart::Parser` component. The parser fails to unfold obsolete line folding (obs-fold) sequences in multipart headers. Applications reflecting these unsanitized multipart variables into response headers are susceptible to HTTP Response Splitting attacks.
The rack gem serves as the fundamental web server interface for the vast majority of Ruby web applications and frameworks. Within this ecosystem, the Rack::Multipart::Parser component is responsible for parsing incoming HTTP requests that utilize the multipart/form-data encoding. This component extracts file uploads, form fields, and their associated metadata into accessible Ruby hashes for application consumption.
The vulnerability, designated as CWE-93 (Improper Neutralization of CRLF Sequences), manifests during the processing of obsolete line folding (obs-fold) within multipart part headers. The parser incorrectly handles situations where a single header field spans multiple lines. Instead of stripping the line breaks, the parser retains the carriage return and line feed characters within the resulting strings.
When a downstream application utilizes these unsanitized strings in outbound HTTP headers, it introduces severe security risks. Specifically, if an application reflects a tainted multipart variable, such as a filename, back to the user in a Content-Disposition or similar header, the preserved CRLF characters terminate the current header context. This behavior directly facilitates HTTP Response Splitting attacks.
The fundamental flaw stems from a failure to strictly implement RFC 5322 Section 2.2.3 and RFC 7230 guidelines regarding header folding. These specifications permit HTTP header values to span multiple lines, provided that any continuation line begins with at least one whitespace character, such as a space or horizontal tab. This mechanism is known as obsolete line folding or obs-fold.
A compliant parser is required to perform an "unfolding" operation before presenting the header value to the application. This unfolding process involves identifying the sequence of a carriage return, line feed, and trailing whitespace, and subsequently replacing the entire sequence with a single space character. This ensures that multi-line headers are condensed into a single continuous string devoid of control characters.
The Rack::Multipart::Parser implementation successfully identified the presence of folded lines but completely omitted the required substitution transformation. As a result, the literal \r\n sequence remained embedded within parsed parameter strings, such as the filename attribute within a Content-Disposition header.
The presence of unescaped control characters in memory bypasses standard application-level validation routines. Developers operating under the assumption that Rack provides compliant, sanitized header extractions process these strings directly. The failure to unfold the header effectively shifts the burden of CRLF neutralization from the middleware parser to the individual application developer.
The vulnerability was mitigated in Rack version 3.2.6 through commit d50c4d3dab62fa80b2a276271d0d4fb338cfa7df. The maintainers introduced a specific regular expression pattern designed to accurately locate and neutralize obsolete line folding sequences during the multipart extraction phase.
The patch defines the following regular expression constant:
OBS_UNFOLD = /\r\n([ \t])/This pattern targets any carriage return and line feed sequence immediately followed by a space or tab. Within the parsing logic, the maintainers implemented a global substitution using the gsub! method against the extracted header components:
content_type.gsub!(OBS_UNFOLD, '\1') if content_type
disposition.gsub!(OBS_UNFOLD, '\1') if dispositionThe substitution replaces the matched CRLF and whitespace sequence with only the captured whitespace character (\1). This operation correctly implements the required RFC unfolding logic directly within the state machine before the attributes are populated into the application parameter hash.
This fix is comprehensive as it sanitizes the variables at the boundary layer. By ensuring that content_type and disposition are properly unfolded early in the execution flow, the patch prevents downstream application logic from ever encountering embedded control characters originating from folded multipart headers.
Exploitation requires an attacker to construct a malicious HTTP POST request utilizing the multipart/form-data content type. Within the payload boundaries, the attacker injects the obs-fold syntax into a part header to conceal a CRLF sequence. The attacker typically targets attributes known to be reflected by the application, such as the file upload filename.
The following proof-of-concept demonstrates the required request structure:
POST /upload HTTP/1.1
Content-Type: multipart/form-data; boundary=AaB03x
--AaB03x
Content-Disposition: form-data; name="upload"; filename="test\r\n
\t.txt"
Content-Type: application/octet-stream; name="file.php"
<?php eval($_POST['x']); ?>
--AaB03x--When the vulnerable Rack parser processes this request, the extracted filename string becomes test\r\n\t.txt. The attacker does not require any specialized privileges or authentication to deliver this payload. The attack vector is purely network-based and relies entirely on standard HTTP protocol mechanics.
Successful exploitation is conditional upon the presence of a downstream sink. The vulnerable web application must extract the tainted multipart metadata and explicitly embed it into an outbound HTTP response header. For example, if the application executes res['Content-Disposition'] = "attachment; filename=\"#{params[:file][:filename]}\"", the server will emit a split response stream, terminating the header block prematurely.
The primary consequence of this vulnerability is HTTP Response Splitting. By controlling the structural boundaries of the HTTP response via injected CRLF sequences, an attacker can arbitrarily define new HTTP header fields or manipulate the response body entirely. This grants the attacker significant influence over the transaction perceived by the victim client.
HTTP Response Splitting directly facilitates severe secondary attack vectors. An attacker can execute Cross-Site Scripting (XSS) by injecting an entirely new, attacker-controlled response body containing malicious JavaScript. Furthermore, in environments utilizing intermediate caching proxies or Content Delivery Networks (CDNs), the vulnerability enables Cache Poisoning and Request Smuggling attacks by desynchronizing the request-response queue.
The assigned CVSS v3.1 score is 4.8 (Medium), represented by the vector CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N. The attack complexity is rated as High because the vulnerability cannot be exploited in isolation. The exploitation chain requires the downstream application implementation to blindly reflect the unsanitized multipart variables, thereby serving as the necessary sink for the injected payload.
The definitive remediation for CVE-2026-26962 is upgrading the rack gem to version 3.2.6 or later. This patch applies the correct RFC unfolding logic at the middleware layer, globally resolving the vulnerability for all relying applications. System administrators should audit their dependency trees using bundle audit to identify instances of vulnerable Rack versions.
For environments where immediate patching is unfeasible, developers must manually sanitize any metadata extracted from multipart uploads prior to reflection. When constructing response headers, applications should utilize utilities such as Rack::Utils.escape_path or explicitly strip carriage return and line feed characters from user-controlled input. This defensive programming practice acts as a robust safeguard against injection attacks regardless of the middleware state.
Security teams can deploy Web Application Firewall (WAF) rules as an interim defense-in-depth measure. WAF signatures can be configured to detect and reject multipart requests containing part headers with line breaks followed by whitespace characters. While this may interrupt legitimate but rare usage of obs-fold by specialized clients, it effectively neutralizes the exploitation vector until the underlying software is updated.
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
rack Rack | >= 3.2.0, < 3.2.6 | 3.2.6 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-93 |
| Attack Vector | Network |
| CVSS Score | 4.8 |
| Impact | HTTP Response Splitting / CRLF Injection |
| Exploit Status | Proof of Concept |
| CISA KEV | False |
Improper Neutralization of CRLF Sequences ('CRLF Injection')
Netflix Lemur, a TLS/SSL certificate management framework, contains a missing authorization check in its certificate export endpoint. Prior to version 1.9.3, the validation logic verifying whether a user had permission to export a certificate was incorrectly placed inside a block that executed only if the selected plugin required a private key. When an authenticated user attempted to export a certificate using a plugin that did not require the private key, the authorization check was bypassed, allowing unauthorized access to the public portions of the certificate and producing misleading audit logs.
A critical security flaw in LibreNMS allows authenticated administrators to execute arbitrary commands by modifying the configured binary path for snmpget and accessing the About page. This occurs due to insufficient verification of the executable file's identity and integrity prior to executing it with shell_exec.
LibreNMS versions prior to 26.7.0 are vulnerable to a stored Cross-Site Scripting (XSS) vulnerability. An authenticated administrator can inject arbitrary HTML or JavaScript into graph descriptions via specific administrative configuration endpoints. When another authenticated user views the affected graph, the unescaped payload executes within their browser context.
An injection vulnerability in LibreNMS's Oxidized integration component allows administrative or network-positioned attackers to achieve stored cross-site scripting (XSS). By setting a malicious oxidized.url endpoint, the server makes outbound queries and processes returned JSON fields containing malicious HTML or JavaScript. These payloads are outputted directly in the web UI without appropriate output encoding.
CVE-2026-17106 (CopyEscape) is a container-to-host arbitrary file-write vulnerability within Docker's archiving and extraction library moby/go-archive. By utilizing a Time-of-Check to Time-of-Use (TOCTOU) race condition during the file-walking stage inside a running container, a malicious container process can force the host engine to produce a compromised tar stream. During client-side extraction, the Docker CLI resolves directory entries through absolute symbolic links, resulting in arbitrary file creation or modification on the host system.
CVE-2026-73974 is a local path traversal vulnerability in linuxfabrik-lib and Linuxfabrik Monitoring Plugins. Under standard monitoring configurations running with elevated privileges via sudo, this flaw can be exploited by an unprivileged local user to read arbitrary root-only files, resulting in local privilege escalation.