diff options
author | Victor Stinner <vstinner@python.org> | 2020-06-12 15:33:19 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-12 15:33:19 (GMT) |
commit | f91a0b6df14d6c5133fe3d5889fad7d84fc0c046 (patch) | |
tree | 44f4aa46375441a6e096db5c4cbdb11daf4d9dd5 | |
parent | f88b578949a034f511dd1b4c1c161351b3ee0db8 (diff) | |
download | cpython-f91a0b6df14d6c5133fe3d5889fad7d84fc0c046.zip cpython-f91a0b6df14d6c5133fe3d5889fad7d84fc0c046.tar.gz cpython-f91a0b6df14d6c5133fe3d5889fad7d84fc0c046.tar.bz2 |
bpo-39073: validate Address parts to disallow CRLF (#19007) (#20450)
Disallow CR or LF in email.headerregistry.Address arguments to guard against header injection attacks.
(cherry picked from commit 614f17211c5fc0e5b828be1d3320661d1038fe8f)
-rw-r--r-- | Lib/email/headerregistry.py | 5 | ||||
-rw-r--r-- | Lib/test/test_email/test_headerregistry.py | 19 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Security/2020-03-15-01-28-36.bpo-39073.6Szd3i.rst | 1 |
3 files changed, 25 insertions, 0 deletions
diff --git a/Lib/email/headerregistry.py b/Lib/email/headerregistry.py index 0fc2231..fafd489 100644 --- a/Lib/email/headerregistry.py +++ b/Lib/email/headerregistry.py @@ -31,6 +31,11 @@ class Address: without any Content Transfer Encoding. """ + + inputs = ''.join(filter(None, (display_name, username, domain, addr_spec))) + if '\r' in inputs or '\n' in inputs: + raise ValueError("invalid arguments; address parts cannot contain CR or LF") + # This clause with its potential 'raise' may only happen when an # application program creates an Address object using an addr_spec # keyword. The email library code itself must always supply username diff --git a/Lib/test/test_email/test_headerregistry.py b/Lib/test/test_email/test_headerregistry.py index 55ecdea..d6f8119 100644 --- a/Lib/test/test_email/test_headerregistry.py +++ b/Lib/test/test_email/test_headerregistry.py @@ -1415,6 +1415,25 @@ class TestAddressAndGroup(TestEmailBase): # with self.assertRaises(ValueError): # Address('foo', 'wők', 'example.com') + def test_crlf_in_constructor_args_raises(self): + cases = ( + dict(display_name='foo\r'), + dict(display_name='foo\n'), + dict(display_name='foo\r\n'), + dict(domain='example.com\r'), + dict(domain='example.com\n'), + dict(domain='example.com\r\n'), + dict(username='wok\r'), + dict(username='wok\n'), + dict(username='wok\r\n'), + dict(addr_spec='wok@example.com\r'), + dict(addr_spec='wok@example.com\n'), + dict(addr_spec='wok@example.com\r\n') + ) + for kwargs in cases: + with self.subTest(kwargs=kwargs), self.assertRaisesRegex(ValueError, "invalid arguments"): + Address(**kwargs) + def test_non_ascii_username_in_addr_spec_raises(self): with self.assertRaises(ValueError): Address('foo', addr_spec='wők@example.com') diff --git a/Misc/NEWS.d/next/Security/2020-03-15-01-28-36.bpo-39073.6Szd3i.rst b/Misc/NEWS.d/next/Security/2020-03-15-01-28-36.bpo-39073.6Szd3i.rst new file mode 100644 index 0000000..6c9447b --- /dev/null +++ b/Misc/NEWS.d/next/Security/2020-03-15-01-28-36.bpo-39073.6Szd3i.rst @@ -0,0 +1 @@ +Disallow CR or LF in email.headerregistry.Address arguments to guard against header injection attacks. |