Skip to content

Commit e431078

Browse files
authored
Merge pull request mjs#270 from growbots/filter-imaplib-login
Prevent IMAP passwords from going to the logging system
2 parents 890fcac + d246988 commit e431078

File tree

2 files changed

+40
-2
lines changed

2 files changed

+40
-2
lines changed

imapclient/imapclient.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import re
1313
from datetime import datetime, date
1414
from operator import itemgetter
15-
from logging import getLogger
15+
from logging import LoggerAdapter, getLogger
1616

1717
from six import moves, iteritems, text_type, integer_types, PY3, binary_type, iterbytes
1818

@@ -30,7 +30,6 @@
3030

3131

3232
logger = getLogger(__name__)
33-
imaplib_logger = getLogger('imapclient.imaplib')
3433

3534
__all__ = ['IMAPClient', 'DELETED', 'SEEN', 'ANSWERED', 'FLAGGED', 'DRAFT', 'RECENT']
3635

@@ -150,6 +149,9 @@ def __init__(self, host, port=None, use_uid=True, ssl=False, stream=False,
150149
logger.debug("Connected to host %s", self.host)
151150

152151
# Small hack to make imaplib log everything to its own logger
152+
imaplib_logger = IMAPlibLoggerAdapter(
153+
getLogger('imapclient.imaplib'), dict()
154+
)
153155
self._imap.debug = 5
154156
self._imap._mesg = imaplib_logger.debug
155157

@@ -1508,3 +1510,17 @@ def debug_trunc(v, maxlen):
15081510
return repr(v)
15091511
hl = maxlen // 2
15101512
return repr(v[:hl]) + "..." + repr(v[-hl:])
1513+
1514+
1515+
class IMAPlibLoggerAdapter(LoggerAdapter):
1516+
"""Adapter preventing IMAP secrets from going to the logging facility."""
1517+
1518+
def process(self, msg, kwargs):
1519+
for command in ("LOGIN", "AUTHENTICATE"):
1520+
if msg.startswith(">") and command in msg:
1521+
msg_start = msg.split(command)[0]
1522+
msg = "{}{} **REDACTED**".format(msg_start, command)
1523+
break
1524+
return super(IMAPlibLoggerAdapter, self).process(
1525+
msg, kwargs
1526+
)

tests/test_imapclient.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import six
1414

15+
from imapclient.imapclient import IMAPlibLoggerAdapter
1516
from imapclient.fixed_offset import FixedOffset
1617
from .testable_imapclient import TestableIMAPClient as IMAPClient
1718
from .imapclient_test import IMAPClientTest
@@ -365,6 +366,27 @@ def test_IMAP_is_patched(self):
365366
self.client._imap._mesg('two')
366367
self.assertIn('DEBUG:imapclient.imaplib:two', log_stream.getvalue())
367368

369+
def test_redacted_password(self):
370+
logger_mock = Mock()
371+
logger_mock.manager.disable = logging.DEBUG
372+
logger_mock.getEffectiveLevel.return_value = logging.DEBUG
373+
374+
adapter = IMAPlibLoggerAdapter(logger_mock, dict())
375+
if six.PY3:
376+
adapter.info("""> b'ICHH1 LOGIN [email protected] "secret"'""")
377+
logger_mock._log.assert_called_once_with(
378+
logging.INFO,
379+
"> b'ICHH1 LOGIN **REDACTED**",
380+
(),
381+
extra={}
382+
)
383+
else:
384+
adapter.info('> ICHH1 LOGIN [email protected] "secret"')
385+
logger_mock.info.assert_called_once_with(
386+
"> ICHH1 LOGIN **REDACTED**",
387+
extra={}
388+
)
389+
368390

369391
class TestTimeNormalisation(IMAPClientTest):
370392

0 commit comments

Comments
 (0)