diff options
| author | Carlton Gibson <carlton.gibson@noumenal.es> | 2022-07-27 10:27:42 +0200 |
|---|---|---|
| committer | Carlton Gibson <carlton.gibson@noumenal.es> | 2022-08-03 08:48:00 +0200 |
| commit | b7d9529cbe0af4adabb6ea5d01ed8dcce3668fb3 (patch) | |
| tree | 4aa0035fdcf98341989045b21967255e35be9070 /tests | |
| parent | 2eb7dedd8f40f911d581d4e7619c046cefe203ce (diff) | |
[4.0.x] Fixed CVE-2022-36359 -- Escaped filename in Content-Disposition header.
Thanks to Motoyasu Saburi for the report.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/responses/test_fileresponse.py | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/tests/responses/test_fileresponse.py b/tests/responses/test_fileresponse.py index f73eb7f19d..77fa440c08 100644 --- a/tests/responses/test_fileresponse.py +++ b/tests/responses/test_fileresponse.py @@ -101,3 +101,38 @@ class FileResponseTests(SimpleTestCase): repr(response), '<FileResponse status_code=200, "application/octet-stream">', ) + + def test_content_disposition_escaping(self): + # fmt: off + tests = [ + ( + 'multi-part-one";\" dummy".txt', + r"multi-part-one\";\" dummy\".txt" + ), + ] + # fmt: on + # Non-escape sequence backslashes are path segments on Windows, and are + # eliminated by an os.path.basename() check in FileResponse. + if sys.platform != "win32": + # fmt: off + tests += [ + ( + 'multi-part-one\\";\" dummy".txt', + r"multi-part-one\\\";\" dummy\".txt" + ), + ( + 'multi-part-one\\";\\\" dummy".txt', + r"multi-part-one\\\";\\\" dummy\".txt" + ) + ] + # fmt: on + for filename, escaped in tests: + with self.subTest(filename=filename, escaped=escaped): + response = FileResponse( + io.BytesIO(b"binary content"), filename=filename, as_attachment=True + ) + response.close() + self.assertEqual( + response.headers["Content-Disposition"], + f'attachment; filename="{escaped}"', + ) |
