From 059881040602c592577924c7978e3a59e705318a Mon Sep 17 00:00:00 2001 From: Ian Ward Date: Mon, 15 Jan 2024 23:35:24 -0500 Subject: [PATCH 1/2] use repr for logging user input --- ckan/views/user.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ckan/views/user.py b/ckan/views/user.py index ba5f2bb679a..4ad4117657b 100644 --- a/ckan/views/user.py +++ b/ckan/views/user.py @@ -675,7 +675,7 @@ def post(self) -> Response: if id in (None, u''): h.flash_error(_(u'Email is required')) return h.redirect_to(u'user.request_reset') - log.info(u'Password reset requested for user "{}"'.format(id)) + log.info('Password reset requested for user {!r}'.format(id)) context: Context = { 'user': current_user.name, @@ -716,7 +716,7 @@ def post(self) -> Response: pass if not user_objs: - log.info(u'User requested reset link for unknown user: {}' + log.info('User requested reset link for unknown user: {!r}' .format(id)) for user_obj in user_objs: From 037e27e37d07fc3e39ecab6d7e34b78ea53328c1 Mon Sep 17 00:00:00 2001 From: Ian Ward Date: Tue, 16 Jan 2024 09:02:53 -0500 Subject: [PATCH 2/2] repr_untrusted and log with proper parameters --- ckan/common.py | 9 +++++++++ ckan/views/user.py | 9 +++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/ckan/common.py b/ckan/common.py index 008857bfcbe..32aaf51f2d7 100644 --- a/ckan/common.py +++ b/ckan/common.py @@ -306,6 +306,15 @@ def aslist(obj: Any, sep: Optional[str] = None, strip: bool = True) -> Any: return [obj] +def repr_untrusted(danger: Any): + """ + repr-format danger and truncate e.g. for logging untrusted input + """ + r = repr(danger) + rtrunc = r[:200] + return rtrunc + '…' if r != rtrunc else r + + local = Local() # This a proxy to the bounded config object diff --git a/ckan/views/user.py b/ckan/views/user.py index 4ad4117657b..72e590547b0 100644 --- a/ckan/views/user.py +++ b/ckan/views/user.py @@ -25,7 +25,8 @@ import ckan.plugins as plugins from ckan import authz from ckan.common import ( - _, config, g, request, current_user, login_user, logout_user, session + _, config, g, request, current_user, login_user, logout_user, session, + repr_untrusted ) from ckan.types import Context, Schema, Response from ckan.lib import signals @@ -675,7 +676,7 @@ def post(self) -> Response: if id in (None, u''): h.flash_error(_(u'Email is required')) return h.redirect_to(u'user.request_reset') - log.info('Password reset requested for user {!r}'.format(id)) + log.info('Password reset requested for user %s', repr_untrusted(id)) context: Context = { 'user': current_user.name, @@ -716,8 +717,8 @@ def post(self) -> Response: pass if not user_objs: - log.info('User requested reset link for unknown user: {!r}' - .format(id)) + log.info('User requested reset link for unknown user: %s', + repr_untrusted(id)) for user_obj in user_objs: log.info(u'Emailing reset link to user: {}'