# HG changeset patch # User John Rouillard # Date 1775425442 14400 # Node ID ee17f62c8341f33c713a72e96a010495494ff32c # Parent dbe30d5032b8b5929ae6f943d6eb5541caca7a7e bug: improve security of eval'ed of session database data. (hexora) Hexora flagged: eval(res[0]) where res[0] is a stored repr of a dictionary. Change these to safe_eval(s) s=res[0] using: eval(s, {'__builtins__': {}}, {}) to wipe all functions and variable references inside the eval. This may be breakable however it's better than it was. There is one place where a username (set by user) is stored as a value, but the username rules prohibit ' or " from being present. Also a repr("us'er") is properly quoted and safe_eval(repr({'user': 'us\'r'})) is properly round tripped. diff -r dbe30d5032b8 -r ee17f62c8341 CHANGES.txt --- a/CHANGES.txt Thu Apr 02 12:26:13 2026 -0400 +++ b/CHANGES.txt Sun Apr 05 17:44:02 2026 -0400 @@ -68,6 +68,7 @@ - refactor mime detection/handling in the rest interface. Better supports some mime types, ads default mime type for files without a mime type (e.g. message contents). Cleaner code. (John Rouillard) +- run hexora and mitigate/fix some medium sev and above. (John Rouillard) Features: diff -r dbe30d5032b8 -r ee17f62c8341 roundup/backends/sessions_rdbms.py --- a/roundup/backends/sessions_rdbms.py Thu Apr 02 12:26:13 2026 -0400 +++ b/roundup/backends/sessions_rdbms.py Sun Apr 05 17:44:02 2026 -0400 @@ -10,6 +10,8 @@ from roundup.anypy.html import html_escape as escape from roundup.backends.sessions_common import SessionCommon +def safe_eval(s): + return eval(s, {"__builtins__": {}}, {}) class BasicDatabase(SessionCommon): ''' Provide a nice encapsulation of an RDBMS table. @@ -42,7 +44,7 @@ if default != self._marker: return default raise KeyError('No such %s "%s"' % (self.name, escape(infoid))) - values = eval(res[0]) + values = safe_eval(res[0]) return values.get(value, None) def getall(self, infoid): @@ -52,7 +54,7 @@ res = self.cursor.fetchone() if not res: raise KeyError('No such %s "%s"' % (self.name, escape(infoid))) - return eval(res[0]) + return safe_eval(res[0]) def set(self, infoid, **newvalues): """ Store all newvalues under key infoid with a timestamp in database. @@ -70,7 +72,7 @@ timestamp = time.time() if res: - values = eval(res[0]) + values = safe_eval(res[0]) else: values = {}