Random832 writes:
I was asking for the current Unpickler class, which currently has a whitelist hook for loading globals,
Callables are globals in this sense. So overriding Unpickler.find_class will allow you to restrict to specified callables. It's not clear to me why you would want more fine-grained control: why not put the argument checking in the object constructor? In most cases that's probably where it's most useful, anyway, by DRY.
to be modified to also have a whitelist hook so that an application can provide a function that looks at a callable and its arguments that the pickle proposes to call, and can choose to either evaluate it, raise an error, or return a substitute value.
I would guess you can already have this by overriding Unpickler.load_reduce and patching Unpickler.dispatch[REDUCE[0]] to the new load_reduce. Is there any other way for a pickle to specify the code to invoke on data supplied by that pickle?
The idea that the pickle format is "inherently unsafe" and cannot be made safe is magical thinking.
I think you're quite wrong. Pickle format itself is inherently unsafe because it allows a pickle to specify code to be executed on data that pickle specifies. Of course that assumes that the problem code somehow got into a Python file on your PYTHON_PATH, but pickle format surely allows that in the absence of a specified threat model that rules it out. I'm sure it's true that some particular uses of pickle format can be safe. But you need to say what you need the code using pickle to do, and what threats you need to be safe against. Note that "pickle format is unsafe" is documented in many places, and the responsibility for security explicitly left up to the user. Not only that but an earlier attempt at "safe pickling" was removed in Python 2.3 (IIRC) since it didn't guarantee safety, and it wasn't considered worth the considerable effort to audit the pickle code for vulnerabilities.
What I am asking for is the ability for application code subclassing Unpickler to control how certain opcodes are evaluated by overriding methods... something that *already exists*, just not for the right ones needed to be adequately expressive.
Of course they already exist, and can be overriden. I guess what you're asking for is a promise that the interface won't change in future versions of pickle.py. That's the only difference between overriding Unpickler.find_class and overriding Unpickler.load_reduce (or any other method).