Skip to content

Commit dac2c06

Browse files
committed
gh-159631: Reject NUL in memoryview credentials in IMAP4.login_plain()
The NUL check ran before the user name and password were converted to bytes, so for a memoryview or another bytes-like object other than bytes and bytearray it compared integer items and never matched.
1 parent e5ef47e commit dac2c06

3 files changed

Lines changed: 9 additions & 1 deletion

File tree

‎Lib/imaplib.py‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -908,12 +908,14 @@ def login_plain(self, user, password):
908908
user = user.encode('utf-8')
909909
if isinstance(password, str):
910910
password = password.encode('utf-8')
911+
user = bytes(user)
912+
password = bytes(password)
911913
if b'\0' in user or b'\0' in password:
912914
raise ValueError("NUL is not allowed in user name or password")
913915
# An empty authorization identity (RFC 4616) makes the server
914916
# derive it from the authentication identity; a non-empty one
915917
# requests proxy authorization and is often rejected.
916-
response = b'\0' + bytes(user) + b'\0' + bytes(password)
918+
response = b'\0' + user + b'\0' + password
917919
return self.authenticate("PLAIN", lambda _: response)
918920

919921

‎Lib/test/test_imaplib.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,10 @@ def test_login_plain_nul(self):
851851
client.login_plain('user\0', 'pass')
852852
with self.assertRaises(ValueError):
853853
client.login_plain('user', b'pa\0ss')
854+
with self.assertRaises(ValueError):
855+
client.login_plain(memoryview(b'user\0'), 'pass')
856+
with self.assertRaises(ValueError):
857+
client.login_plain('user', memoryview(b'pa\0ss'))
854858

855859
def test_aborted_authentication(self):
856860
class MyServer(SimpleIMAPHandler):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:meth:`imaplib.IMAP4.login_plain` now rejects NUL in a user name or password
2+
given as a :class:`memoryview` or another :term:`bytes-like object`.

0 commit comments

Comments
 (0)