Mar 12, 2026·5 min read·2 visits
Tornado < 6.5.5 fails to sanitize semicolons and control characters in cookie attributes, enabling HTTP header injection and arbitrary cookie manipulation. Organizations must upgrade to v6.5.5.
Tornado versions prior to v6.5.5 contain a vulnerability in the RequestHandler.set_cookie method where cookie attributes are not properly validated. This flaw permits attackers to inject control characters and semicolons, leading to HTTP header injection or unauthorized cookie attribute manipulation. The issue exposes web applications to session fixation, security flag overriding, and potential response splitting risks.
Tornado is a Python web framework and asynchronous networking library. The RequestHandler.set_cookie method is responsible for generating HTTP Set-Cookie headers within application responses. This method accepts multiple parameters corresponding to cookie attributes, including the cookie name, domain, path, and SameSite directives.
Prior to version 6.5.5, Tornado failed to adequately sanitize these attribute parameters. While the cookie value itself received some validation, the surrounding attributes were not checked for control characters or structural delimiters. This omission creates a vulnerability classified under CWE-113 (Improper Neutralization of CRLF Sequences in HTTP Headers) and CWE-159 (Improper Handling of Invalid Characters).
The primary consequence of this validation failure is HTTP header injection, specifically cookie attribute injection. Attackers supplying crafted input to vulnerable application endpoints can manipulate the resulting HTTP response headers. This capability allows attackers to bypass intended security policies or modify session management behaviors.
The HTTP protocol uses the semicolon character as a structural delimiter within the Set-Cookie header. Each semicolon separates the primary cookie key-value pair from subsequent configuration attributes. A standard header takes the format Set-Cookie: name=value; Domain=example.com; Path=/.
The root cause resides in the implementation of tornado/web.py in versions prior to 6.5.5. The library validated the primary cookie value against a restricted set of control characters (\x00 through \x20). However, it completely omitted validation for the name, domain, path, and samesite arguments.
Furthermore, the original validation logic failed to account for the Delete character (\x7F) and the semicolon (;) across all attribute fields. When an application passes user-controlled input into these attribute parameters, the lack of semicolon sanitization allows the input string to prematurely terminate the current attribute declaration.
The vulnerability manifests when developers utilize user-supplied data to define cookie attributes without independent sanitization. The following code snippet demonstrates the vulnerable pattern where user input directly populates the domain parameter.
class VulnerableHandler(tornado.web.RequestHandler):
def get(self):
user_input = "example.com; Secure; HttpOnly"
self.set_cookie("session", "secret", domain=user_input)The patch introduced in Tornado v6.5.5 addresses this by centralizing validation for all cookie attributes. The maintainers implemented a strict regular expression check across the name, domain, path, and samesite variables before constructing the header.
for attr_name, attr_value in [
("name", name),
("domain", domain),
("path", path),
("samesite", samesite),
]:
if attr_value is not None and re.search(r"[\x00-\x20\x3b\x7f]", attr_value):
raise http.cookies.CookieError(
f"Invalid cookie attribute {attr_name}={attr_value!r} for cookie {name!r}"
)This regex comprehensive evaluates the input against the exact set of forbidden byte values. By explicitly checking for \x3b (semicolon) and \x7f (delete), the patch closes the structural manipulation vector and prevents header termination attacks.
Exploitation requires a specific application configuration where user input routes directly into one of the vulnerable set_cookie parameters. If this condition is met, the attacker supplies a payload containing a semicolon followed by arbitrary cookie attributes.
When the application processes the payload example.com; Secure; HttpOnly within the domain parameter, the framework constructs a structurally altered header. The resulting HTTP response contains Set-Cookie: session=secret; Domain=example.com; Secure; HttpOnly.
The HTTP client parses this response and processes the injected attributes as legitimate directives from the server. The attacker successfully forces the Secure and HttpOnly flags onto the session cookie, regardless of the developer's original intent.
Injection of control characters like carriage return (\r) and line feed (\n) within these fields escalates the attack to full HTTP Response Splitting. This allows the attacker to terminate the entire HTTP header block and inject a malicious response body directly into the victim's client.
The direct impact of this vulnerability is the unauthorized modification of HTTP response headers. By injecting arbitrary cookie attributes, an attacker manipulates how the victim's browser handles the affected cookie. This manipulation directly affects session security and client-side state management.
If an attacker injects a Domain or Path attribute, they can expand the scope of a sensitive cookie, causing the victim's browser to transmit it to unintended endpoints or subdomains. Alternatively, injecting expiration directives can force premature session termination or extend a session beyond intended limits.
While the immediate vector focuses on cookie attributes, the lack of control character validation introduces broader HTTP header injection risks. If the underlying server infrastructure does not independently sanitize carriage return and line feed characters, attackers can inject entirely new HTTP headers, bypass security mechanisms like Content Security Policy (CSP), or execute cross-site scripting (XSS) attacks via response splitting.
The definitive remediation for this vulnerability is upgrading the Tornado framework to version 6.5.5 or later. This version contains the comprehensive regular expression validation that neutralizes structural delimiters and control characters across all cookie attributes.
For applications where immediate upgrading is not feasible, developers must implement strict input validation on all data passed to set_cookie. Applications must reject any input containing semicolons, carriage returns, line feeds, or other control characters before invoking the framework method.
Security teams should review application codebases for instances of set_cookie and audit the data flow reaching the domain, path, and samesite arguments. Implementing a Web Application Firewall (WAF) rule to detect semicolons and control characters in parameters destined for cookie configuration provides effective defense-in-depth.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Tornado Tornadoweb | < 6.5.5 | 6.5.5 |
| Attribute | Detail |
|---|---|
| Vulnerability Class | HTTP Header / Cookie Attribute Injection |
| CWE ID | CWE-113, CWE-159 |
| Attack Vector | Network |
| Authentication Required | None |
| Exploit Status | PoC Available |
| Fixed Version | v6.5.5 |
Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Response Splitting')