Skip to content

Commit dab9e87

Browse files
Fix multipart injection (aio-libs#12104)
Co-authored-by: mingi jung <[email protected]>
1 parent 8a631e7 commit dab9e87

2 files changed

Lines changed: 16 additions & 5 deletions

File tree

aiohttp/formdata.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ def add_field(
7070
raise TypeError(
7171
"content_type must be an instance of str. Got: %s" % content_type
7272
)
73+
if "\r" in content_type or "\n" in content_type:
74+
raise ValueError(
75+
"Newline or carriage return detected in headers. "
76+
"Potential header injection attack."
77+
)
7378
headers[hdrs.CONTENT_TYPE] = content_type
7479
self._is_multipart = True
7580

tests/test_formdata.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,18 @@ async def test_formdata_textio_charset(buf: bytearray, writer: StreamWriter) ->
7575
assert b"\x93\xfa\x96{" in buf
7676

7777

78-
def test_invalid_formdata_content_type() -> None:
78+
@pytest.mark.parametrize("val", (0, 0.1, {}, [], b"foo"))
79+
def test_invalid_type_formdata_content_type(val: object) -> None:
7980
form = FormData()
80-
invalid_vals = [0, 0.1, {}, [], b"foo"]
81-
for invalid_val in invalid_vals:
82-
with pytest.raises(TypeError):
83-
form.add_field("foo", "bar", content_type=invalid_val) # type: ignore[arg-type]
81+
with pytest.raises(TypeError):
82+
form.add_field("foo", "bar", content_type=val) # type: ignore[arg-type]
83+
84+
85+
@pytest.mark.parametrize("val", ("\r", "\n", "a\ra\n", "a\na\r"))
86+
def test_invalid_value_formdata_content_type(val: str) -> None:
87+
form = FormData()
88+
with pytest.raises(ValueError):
89+
form.add_field("foo", "bar", content_type=val)
8490

8591

8692
def test_invalid_formdata_filename() -> None:

0 commit comments

Comments
 (0)