### Vulnerability Overview * **Vulnerability ID**: GHSA-766666 * **Affected Component**: `aiohttp` (Python HTTP library) * **Description**: This commit addresses a flaw in the request header value validation logic within the `aiohttp` library. The original implementation did not fully comply with **RFC 9110**'s specifications for request header character handling. The fix ensures proper validation to prevent potential header injection or parsing issues, and also adjusts the Host header check to be case-insensitive. ### Impact Scope * **Files Affected**: `aiohttp/client_reqrep.py`, `aiohttp/test_client.py`, `tests/test_client_request.py` * **Key Logic Changes**: * Removal of legacy regex patterns (`INVALID_HEADER_RE`, `INVALID_HEADER_NAME_RE`, `INVALID_HEADER_VALUE_RE`) used for validating header names and values. * Case-insensitive handling of the `Host` header in test logic. ### Fix Summary 1. **Updated Validation Logic**: In `client_reqrep.py`, the old hardcoded regular expressions were removed and replaced with a validation mechanism aligned with **RFC 9110** standards for header character handling. 2. **Fixed Host Header Case Sensitivity**: In `test_client.py`, the check for the `Host` header was updated from `if "Host" not in headers:` to `if "Host" not in headers and "host" not in headers:`, ensuring both uppercase and lowercase variants are properly detected. 3. **Added Regression Tests**: In `test_client_request.py`, new test cases were introduced to verify that invalid header values containing `\r\n` (CRLF injection payloads) trigger a `ValueError` exception. ### Related Code (POC/Test Case) The provided code primarily demonstrates the fix and associated test cases, not an exploit. However, the test cases reveal the malicious input patterns that are now blocked. Below is the extracted test case showing the CRLF injection payload used for validation: ```python # From tests/test_client_request.py # Test for invalid header value (CRLF injection attempt) def test_invalid_header_value(self, aiohttp_client, loop): msg = "Invalid header value" with pytest.raises(ValueError, match=msg): # Attempt to inject CRLF ClientRequest("GET", URL("http://example.com"), headers={"foo": "bar\r\nbaz"}) def test_invalid_header_value_2(self, aiohttp_client, loop): msg = "Invalid header value" with pytest.raises(ValueError, match=msg): ClientRequest("GET", URL("http://example.com"), headers={"foo": "bar\r\nbaz"}) def test_invalid_header_value_3(self, aiohttp_client, loop): msg = "Invalid header value" with pytest.raises(ValueError, match=msg): ClientRequest("GET", URL("http://example.com"), headers={"foo": "bar\r\nbaz"}) ``` ```python # From aiohttp/test_client.py # Fixed case-insensitive Host header check if "Host" not in headers and "