|
9 | 9 | SimpleCookie, |
10 | 10 | _unquote as simplecookie_unquote, |
11 | 11 | ) |
| 12 | +from unittest.mock import patch |
12 | 13 |
|
13 | 14 | import pytest |
14 | 15 |
|
@@ -1163,7 +1164,7 @@ def test_parse_set_cookie_headers_ctl_chars_from_octal( |
1163 | 1164 |
|
1164 | 1165 |
|
1165 | 1166 | def test_parse_set_cookie_headers_literal_ctl_chars() -> None: |
1166 | | - """Ensure literal control characters in a cookie value don't crash the parser. |
| 1167 | + r"""Ensure literal control characters in a cookie value don't crash the parser. |
1167 | 1168 |
|
1168 | 1169 | If the raw header itself contains a control character (e.g. BEL \\x07), |
1169 | 1170 | both the decoded value and coded_value are unsalvageable. The parser |
@@ -1650,7 +1651,7 @@ def test_parse_cookie_header_empty_key_in_fallback( |
1650 | 1651 |
|
1651 | 1652 |
|
1652 | 1653 | def test_parse_cookie_header_literal_ctl_chars() -> None: |
1653 | | - """Ensure literal control characters in a cookie value don't crash the parser. |
| 1654 | + r"""Ensure literal control characters in a cookie value don't crash the parser. |
1654 | 1655 |
|
1655 | 1656 | If the raw header itself contains a control character (e.g. BEL \\x07), |
1656 | 1657 | the cookie is unsalvageable. The parser should gracefully skip it. |
@@ -1850,3 +1851,37 @@ def test_unquote_compatibility_with_simplecookie(test_value: str) -> None: |
1850 | 1851 | f"our={_unquote(test_value)!r}, " |
1851 | 1852 | f"SimpleCookie={simplecookie_unquote(test_value)!r}" |
1852 | 1853 | ) |
| 1854 | + |
| 1855 | + |
| 1856 | +@pytest.fixture |
| 1857 | +def mock_strict_morsel(): |
| 1858 | + original_setstate = Morsel.__setstate__ |
| 1859 | + |
| 1860 | + def _mock_setstate(self: Morsel[str], state: dict[str, str]) -> None: |
| 1861 | + if any(ord(c) < 32 for c in state.get("value", "")): |
| 1862 | + raise CookieError() |
| 1863 | + original_setstate(self, state) |
| 1864 | + |
| 1865 | + with patch( |
| 1866 | + "aiohttp._cookie_helpers.Morsel.__setstate__", |
| 1867 | + autospec=True, |
| 1868 | + side_effect=_mock_setstate, |
| 1869 | + ): |
| 1870 | + yield |
| 1871 | + |
| 1872 | + |
| 1873 | +def test_cookie_helpers_cve_fallback(mock_strict_morsel) -> None: |
| 1874 | + m: Morsel[str] = Morsel() |
| 1875 | + assert helpers._safe_set_morsel_state(m, "k", "v\n", "v\\012") is True |
| 1876 | + assert m.value == "v\\012" |
| 1877 | + |
| 1878 | + assert helpers._safe_set_morsel_state(Morsel(), "k", "v\n", "v\n") is False |
| 1879 | + |
| 1880 | + cookie: Morsel[str] = Morsel() |
| 1881 | + cookie._key, cookie._value, cookie._coded_value = "k", "v\n", "v\n" # type: ignore[attr-defined] |
| 1882 | + assert preserve_morsel_with_coded_value(cookie) is cookie |
| 1883 | + |
| 1884 | + assert parse_cookie_header("f=b\x07r;") == [] |
| 1885 | + assert parse_cookie_header("f=b\x07r") == [] |
| 1886 | + assert parse_cookie_header("f=\"b\x07r\";") == [] |
| 1887 | + assert parse_set_cookie_headers(["f=\"b\x07r\";"]) == [] |
0 commit comments