Permalink
Browse files

Merge pull request #270 from growbots/filter-imaplib-login

Prevent IMAP passwords from going to the logging system
  • Loading branch information...
mjs committed Aug 22, 2017
2 parents 890fcac + d246988 commit e43107864a9845c4064f9602650afee52330dd03
Showing with 40 additions and 2 deletions.
  1. +18 −2 imapclient/imapclient.py
  2. +22 −0 tests/test_imapclient.py
View
@@ -12,7 +12,7 @@
import re
from datetime import datetime, date
from operator import itemgetter
from logging import getLogger
from logging import LoggerAdapter, getLogger
from six import moves, iteritems, text_type, integer_types, PY3, binary_type, iterbytes
@@ -30,7 +30,6 @@
logger = getLogger(__name__)
imaplib_logger = getLogger('imapclient.imaplib')
__all__ = ['IMAPClient', 'DELETED', 'SEEN', 'ANSWERED', 'FLAGGED', 'DRAFT', 'RECENT']
@@ -150,6 +149,9 @@ def __init__(self, host, port=None, use_uid=True, ssl=False, stream=False,
logger.debug("Connected to host %s", self.host)
# Small hack to make imaplib log everything to its own logger
imaplib_logger = IMAPlibLoggerAdapter(
getLogger('imapclient.imaplib'), dict()
)
self._imap.debug = 5
self._imap._mesg = imaplib_logger.debug
@@ -1508,3 +1510,17 @@ def debug_trunc(v, maxlen):
return repr(v)
hl = maxlen // 2
return repr(v[:hl]) + "..." + repr(v[-hl:])
class IMAPlibLoggerAdapter(LoggerAdapter):
"""Adapter preventing IMAP secrets from going to the logging facility."""
def process(self, msg, kwargs):
for command in ("LOGIN", "AUTHENTICATE"):
if msg.startswith(">") and command in msg:
msg_start = msg.split(command)[0]
msg = "{}{} **REDACTED**".format(msg_start, command)
break
return super(IMAPlibLoggerAdapter, self).process(
msg, kwargs
)
View
@@ -12,6 +12,7 @@
import six
from imapclient.imapclient import IMAPlibLoggerAdapter
from imapclient.fixed_offset import FixedOffset
from .testable_imapclient import TestableIMAPClient as IMAPClient
from .imapclient_test import IMAPClientTest
@@ -365,6 +366,27 @@ def test_IMAP_is_patched(self):
self.client._imap._mesg('two')
self.assertIn('DEBUG:imapclient.imaplib:two', log_stream.getvalue())
def test_redacted_password(self):
logger_mock = Mock()
logger_mock.manager.disable = logging.DEBUG
logger_mock.getEffectiveLevel.return_value = logging.DEBUG
adapter = IMAPlibLoggerAdapter(logger_mock, dict())
if six.PY3:
adapter.info("""> b'ICHH1 LOGIN foo@bar.org "secret"'""")
logger_mock._log.assert_called_once_with(
logging.INFO,
"> b'ICHH1 LOGIN **REDACTED**",
(),
extra={}
)
else:
adapter.info('> ICHH1 LOGIN foo@bar.org "secret"')
logger_mock.info.assert_called_once_with(
"> ICHH1 LOGIN **REDACTED**",
extra={}
)
class TestTimeNormalisation(IMAPClientTest):

0 comments on commit e431078

Please sign in to comment.