[Python-Dev] Re: [Python-checkins] CVS: python/dist/src/Lib pickle.py,1.38,1.39
Guido van Rossum
guido@beopen.com
Fri, 15 Sep 2000 11:24:47 -0500
> --- 578,624 ----
>
> def load_string(self):
> ! rep = self.readline()[:-1]
> ! if not self._is_string_secure(rep):
> ! raise ValueError, "insecure string pickle"
> ! self.append(eval(rep,
> {'__builtins__': {}})) # Let's be careful
> dispatch[STRING] = load_string
> +
> + def _is_string_secure(self, s):
> + """Return true if s contains a string that is safe to eval
> +
> + The definition of secure string is based on the implementation
> + in cPickle. s is secure as long as it only contains a quoted
> + string and optional trailing whitespace.
> + """
> + q = s[0]
> + if q not in ("'", '"'):
> + return 0
> + # find the closing quote
> + offset = 1
> + i = None
> + while 1:
> + try:
> + i = s.index(q, offset)
> + except ValueError:
> + # if there is an error the first time, there is no
> + # close quote
> + if offset == 1:
> + return 0
> + if s[i-1] != '\\':
> + break
> + # check to see if this one is escaped
> + nslash = 0
> + j = i - 1
> + while j >= offset and s[j] == '\\':
> + j = j - 1
> + nslash = nslash + 1
> + if nslash % 2 == 0:
> + break
> + offset = i + 1
> + for c in s[i+1:]:
> + if ord(c) > 32:
> + return 0
> + return 1
>
> def load_binstring(self):
Hm... This seems to add a lot of work to a very common item in
pickles.
I had a different idea on how to make this safe from abuse: pass eval
a globals dict with an empty __builtins__ dict, as follows:
{'__builtins__': {}}.
Have you timed it?
--Guido van Rossum (home page: http://www.pythonlabs.com/~guido/)