diff --git a/src/ircdb.py b/src/ircdb.py index c405932f2..40d513384 100644 --- a/src/ircdb.py +++ b/src/ircdb.py @@ -516,15 +516,15 @@ class IrcUserCreator(Creator): def ignore(self, rest, lineno): self._checkId() - self.u.ignore = bool(eval(rest)) + self.u.ignore = bool(utils.gen.safeEval(rest)) def secure(self, rest, lineno): self._checkId() - self.u.secure = bool(eval(rest)) + self.u.secure = bool(utils.gen.safeEval(rest)) def hashed(self, rest, lineno): self._checkId() - self.u.hashed = bool(eval(rest)) + self.u.hashed = bool(utils.gen.safeEval(rest)) def password(self, rest, lineno): self._checkId() @@ -580,11 +580,11 @@ class IrcChannelCreator(Creator): def lobotomized(self, rest, lineno): self._checkId() - self.c.lobotomized = bool(eval(rest)) + self.c.lobotomized = bool(utils.gen.safeEval(rest)) def defaultallow(self, rest, lineno): self._checkId() - self.c.defaultAllow = bool(eval(rest)) + self.c.defaultAllow = bool(utils.gen.safeEval(rest)) def capability(self, rest, lineno): self._checkId() diff --git a/src/utils/gen.py b/src/utils/gen.py index 005e27806..c2275b03e 100644 --- a/src/utils/gen.py +++ b/src/utils/gen.py @@ -165,7 +165,7 @@ def saltHash(password, salt=None, hash='sha'): return '|'.join([salt, hasher((salt + password).encode('utf8')).hexdigest()]) _astStr2 = ast.Str if minisix.PY2 else ast.Bytes -def safeEval(s, namespace={'True': True, 'False': False, 'None': None}): +def safeEval(s, namespace=None): """Evaluates s, safely. Useful for turning strings into tuples/lists/etc. without unsafely using eval().""" try: @@ -196,7 +196,12 @@ def safeEval(s, namespace={'True': True, 'False': False, 'None': None}): else: return False if checkNode(node): - return eval(s, namespace, namespace) + if namespace is None: + return eval(s, namespace, namespace) + else: + # Probably equivalent to eval() because checkNode(node) is True, + # but it's an extra security. + return ast.literal_eval(node) else: raise ValueError(format('Unsafe string: %q', s))