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 ba5f2bb679a..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(u'Password reset requested for user "{}"'.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(u'User requested reset link for unknown user: {}' - .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: {}'