CVE-2026-3644 Overview
CVE-2026-3644 is an input validation flaw in the Python standard library http.cookies module. The vulnerability stems from an incomplete fix for CVE-2026-0672, which originally rejected control characters in http.cookies.Morsel. The remediation missed several code paths, including Morsel.update(), the |= operator, and unpickling operations. Additionally, BaseCookie.js_output() lacks the output validation that BaseCookie.output() enforces. Attackers with the ability to influence cookie values can inject control characters that bypass validation, leading to potential header manipulation or downstream parsing issues. The vulnerability is categorized under [CWE-20] Improper Input Validation.
Critical Impact
Control character injection through unpatched Morsel update paths can bypass cookie validation, enabling HTTP header manipulation in applications relying on Python's standard library cookie handling.
Affected Products
- Python CPython interpreter (versions including the incomplete CVE-2026-0672 fix)
- Applications using http.cookies.Morsel.update() or the |= operator
- Applications calling BaseCookie.js_output() for JavaScript cookie rendering
Discovery Timeline
- 2026-03-16 - CVE-2026-3644 published to NVD
- 2026-03-17 - Last updated in NVD database
Technical Details for CVE-2026-3644
Vulnerability Analysis
The Python http.cookies module provides classes for parsing and constructing HTTP cookie headers. The original fix for CVE-2026-0672 added control character rejection to Morsel value assignment, preventing characters such as carriage return and line feed from being stored in cookie values. The fix focused on direct attribute setters but did not extend coverage to alternative mutation paths.
The Morsel.update() method, inherited from dict, accepts a mapping or iterable and writes values without invoking the validation logic. The |= operator, introduced for dictionary merging in Python 3.9, follows the same unvalidated code path. Unpickling a Morsel instance reconstructs the object state directly, again skipping the value sanitization routines.
Separately, BaseCookie.js_output() generates JavaScript-formatted cookie assignments for client-side rendering. While BaseCookie.output() validates each Morsel before emitting header lines, js_output() was not updated with equivalent checks. An attacker who controls cookie input can inject \r\n sequences or other control characters into rendered output.
Root Cause
The root cause is incomplete enforcement of input validation invariants. Validation logic was attached to specific setter functions rather than centralized in a single chokepoint that all mutation paths must traverse. This allowed update(), |=, and unpickling to bypass the check entirely. The js_output() divergence reflects parallel rendering paths that were not kept in sync when output sanitization was added.
Attack Vector
Exploitation requires the attacker to influence cookie keys or values processed by a vulnerable Python application. In web applications that accept user-controlled data and use Morsel.update() or dictionary-merge syntax to populate cookies, the attacker can inject control characters. When such cookies are later serialized through js_output(), the malicious characters appear in the output without filtering. This can enable HTTP response splitting, header injection, or client-side parser confusion. Successful exploitation requires low privileges and no user interaction, but depends on application logic that exposes the unvalidated paths. Refer to the Python Security Announce Thread for technical details.
// No verified exploit code is published.
// See upstream CPython commits for the validation gaps and fixes:
// - https://github.com/python/cpython/commit/57e88c1cf95e1481b94ae57abe1010469d47a6b4
// - https://github.com/python/cpython/commit/62ceb396fcbe69da1ded3702de586f4072b590dd
// - https://github.com/python/cpython/commit/d16ecc6c3626f0e2cc8f08c309c83934e8a979dd
Detection Methods for CVE-2026-3644
Indicators of Compromise
- HTTP responses containing unexpected \r\n or other control character sequences within Set-Cookie headers or inline JavaScript cookie assignments.
- Application logs showing cookie values that include non-printable bytes after passing through Morsel.update() or |= operations.
- Anomalous pickle deserialization events restoring Morsel objects from untrusted sources.
Detection Strategies
- Audit Python source code for direct use of Morsel.update(), the |= operator on Morsel instances, and BaseCookie.js_output() with user-influenced data.
- Add runtime assertions or wrappers that validate cookie values against the standard cookie grammar before rendering responses.
- Inspect web application firewall logs for inbound requests containing encoded control characters targeting cookie parameters.
Monitoring Recommendations
- Capture and review outbound HTTP headers to identify CRLF sequences indicative of header injection attempts.
- Monitor Python application telemetry for unpickling operations sourced from network-attached or user-controlled storage.
- Track the deployed Python interpreter version across hosts and flag environments lacking the upstream patch.
How to Mitigate CVE-2026-3644
Immediate Actions Required
- Upgrade Python to a release containing the CPython commits referenced in the GitHub Pull Request Review.
- Inventory applications using http.cookies and confirm whether they invoke Morsel.update(), |=, or js_output() with untrusted input.
- Disable or restrict unpickling of Morsel objects originating from external sources.
Patch Information
The upstream CPython project addressed the gap through three commits referenced in the advisory: commit 57e88c1, commit 62ceb39, and commit d16ecc6. Discussion and review are tracked in GitHub Issue 145599 and Pull Request 145600. Apply vendor-supplied Python interpreter updates from your operating system or Python distribution.
Workarounds
- Wrap Morsel.update() calls in application code with a custom validator that rejects control characters before assignment.
- Replace calls to BaseCookie.js_output() with BaseCookie.output() where possible, or apply explicit validation on the rendered string.
- Treat any cookie content sourced from external systems as untrusted and sanitize it prior to reuse in HTTP responses.
# Verify the installed Python version and apply distribution updates
python3 --version
# Example: upgrade Python on Debian-based systems
sudo apt-get update && sudo apt-get install --only-upgrade python3
# Example: upgrade in a virtual environment using pyenv
pyenv install --list | grep 3.
pyenv install <patched-version>
pyenv global <patched-version>
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


