Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Lib/imaplib.py
Original file line number Diff line number Diff line change
Expand Up @@ -908,12 +908,14 @@ def login_plain(self, user, password):
user = user.encode('utf-8')
if isinstance(password, str):
password = password.encode('utf-8')
user = bytes(user)
password = bytes(password)
if b'\0' in user or b'\0' in password:
raise ValueError("NUL is not allowed in user name or password")
# An empty authorization identity (RFC 4616) makes the server
# derive it from the authentication identity; a non-empty one
# requests proxy authorization and is often rejected.
response = b'\0' + bytes(user) + b'\0' + bytes(password)
response = b'\0' + user + b'\0' + password
return self.authenticate("PLAIN", lambda _: response)


Expand Down
4 changes: 4 additions & 0 deletions Lib/test/test_imaplib.py
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,10 @@ def test_login_plain_nul(self):
client.login_plain('user\0', 'pass')
with self.assertRaises(ValueError):
client.login_plain('user', b'pa\0ss')
with self.assertRaises(ValueError):
client.login_plain(memoryview(b'user\0'), 'pass')
with self.assertRaises(ValueError):
client.login_plain('user', memoryview(b'pa\0ss'))

def test_aborted_authentication(self):
class MyServer(SimpleIMAPHandler):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
:meth:`imaplib.IMAP4.login_plain` now rejects NUL in a user name or password
given as a :class:`memoryview` or another :term:`bytes-like object`.
Loading