Exploiting Misuse of Python's “Pickle”
blog.nelhage.com
blog.nelhage.com
No, pickling and unpickling files in your user's data-dir isn't a big deal, until it is because your users wanted to share their data online. They'll sync their data-folder with Dropbox, and then their account gets compromised, and the next time they launch your program they've got a virus. They'll download a 'completed savegame' from a sketchy site, and now they've got a virus. They'll get a phishing e-mail, but it's not one of those zips or exes or whatever, it's a file-format they know is your program, and surely that's safe, right?
Don't make your file formats insecure. Don't pickle.
I don't like people making such strong statements about what others should and should not do, based on issues in some situations.
Unless you're storing an HMAC alongside your pickled blob, and verifying that HMAC on the deserialization side, you should not trust pickle for anything. (Even then, it's still potentially dangerous, because in a large project some other dev who doesn't understand the issue could come along and write a new thing to deserialize the same pickles and not check the HMAC).
I dislike such strong statements. When I use pickle, it's often a dump of where a computation is up to, or a simple cache. How can that be exploited? Someone would need to be meddling on my filesystem, in which case I'm already screwed. What risks am I opening myself up to? Why should I not trust it for my use case?
You can mitigate the dangers of pickle by educating junior devs or people new to python, by having a strong culture of code reviews with experienced reviewers, by having a style guide that explicitly prohibits pickle except in exceptional cases.
... Or you can just not use it in the first place and make it trivial for newcomers to your codebase to use safer serialization methods.
I'll go ahead and keep using pickle. It makes me more productive, despite never unpickling untrusted data.
By the way, reading XML is a security risk, too...
Never ever.
Or namedtuple, one of my favorite tools.
>>> cPickle.dump(dict(foo=42), sys.stdout)
(dp1
S'foo'
p2
I42
s.Of course, one can argue you can already to it with docker :)
It's not a drop in replacement but it's very effective