From 893308e340858fd08597cd2d6f019f894db479e8 Mon Sep 17 00:00:00 2001 From: Brian Korty Date: Tue, 1 Sep 2020 10:55:06 -0400 Subject: [PATCH] Obscure password in debug logs. Obscure password in the postgres connection DSN when logging in debug mode. Will also not print the DSN with obscured password when failing to connect at start up. --- sprockets_postgres.py | 20 +++++++++++++++++--- tests.py | 16 ++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/sprockets_postgres.py b/sprockets_postgres.py index 9ca953e..02c895d 100644 --- a/sprockets_postgres.py +++ b/sprockets_postgres.py @@ -444,7 +444,9 @@ class ApplicationMixin: if self._postgres_pool: self._postgres_pool.close() - LOGGER.debug('Connecting to %s', url) + safe_url = self._obscure_url_password(url) + LOGGER.debug('Connecting to %s', safe_url) + try: self._postgres_pool = await pool.Pool.from_pool_fill( url, @@ -475,13 +477,25 @@ class ApplicationMixin: DEFAULT_POSTGRES_CONNECTION_TTL))) except (psycopg2.OperationalError, psycopg2.Error) as error: # pragma: nocover - LOGGER.warning('Error connecting to PostgreSQL on startup: %s', - error) + LOGGER.warning( + 'Error connecting to PostgreSQL on startup with %s: %s', + safe_url, error) return False self._postgres_connected.set() LOGGER.debug('Connected to Postgres') return True + @staticmethod + def _obscure_url_password(url): + """Generate log safe url with password obscured.""" + parsed = parse.urlparse(url) + if parsed.password: + netloc = '{}:*****@{}:{}'.format(parsed.username, + parsed.hostname, + parsed.port) + url = parse.urlunparse(parsed._replace(netloc=netloc)) + return url + async def _postgres_on_start(self, _app: web.Application, loop: ioloop.IOLoop): diff --git a/tests.py b/tests.py index dde98b6..37eb137 100644 --- a/tests.py +++ b/tests.py @@ -579,6 +579,22 @@ class MissingURLTestCase(unittest.TestCase): obj.stop.assert_called_once() +class ObscurePasswordUrlTestCase(unittest.TestCase): + + def test_passwords_obscured(self): + for url, expected in { + 'postgresql://server:5432/database': + 'postgresql://server:5432/database', + 'postgresql://username:password@server:5432/database': + 'postgresql://username:*****@server:5432/database', + 'postgresql://username@server/database': + 'postgresql://username@server/database' + }.items(): + result = \ + sprockets_postgres.ApplicationMixin._obscure_url_password(url) + self.assertEqual(result, expected) + + SRV = collections.namedtuple( 'SRV', ['host', 'port', 'priority', 'weight', 'ttl'])