From: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Date: Wed, 27 May 2020 23:17:52 +0000 (-0700) Subject: bpo-39073: validate Address parts to disallow CRLF (GH-19007) (#19224) X-Git-Tag: v3.6.11rc1~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7df32f844efed33ca781a016017eab7050263b90;p=thirdparty%2FPython%2Fcpython.git bpo-39073: validate Address parts to disallow CRLF (GH-19007) (#19224) Disallow CR or LF in email.headerregistry.Address arguments to guard against header injection attacks. (cherry picked from commit 614f17211c5fc0e5b828be1d3320661d1038fe8f) Co-authored-by: Ashwin Ramaswami Co-authored-by: Ashwin Ramaswami --- diff --git a/Lib/email/headerregistry.py b/Lib/email/headerregistry.py index f5be87f4d243..6e86b3b26c92 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 d1007099f666..08634daa7f61 100644 --- a/Lib/test/test_email/test_headerregistry.py +++ b/Lib/test/test_email/test_headerregistry.py @@ -1435,6 +1435,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 000000000000..6c9447b897bf --- /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.