Mercurial > p > roundup > code
changeset 8553:ee17f62c8341
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.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Sun, 05 Apr 2026 17:44:02 -0400 |
| parents | dbe30d5032b8 |
| children | 92aecf6c5c09 |
| files | CHANGES.txt roundup/backends/sessions_rdbms.py |
| diffstat | 2 files changed, 6 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- 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:
--- 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 = {}
