3 ms·
Ah thanks, that sounds like pickling in Python. It took forever for them to understand that unpickling untrested data was a security hole.
by throwaway81523 5y ago
Ah thanks, that sounds like pickling in Python. It took forever for them to understand that unpickling untrested data was a security hole.
- formerly_proven 5y ago2.2 tried to create a "safe for unpickling" way (https://docs.python.org/2.2/lib/pickle-sec.html https://docs.python.org/2.2/lib/pickle-sec.html) which unsurprisingly failed (https://www.python.org/dev/peps/pep-0307/ https://www.python.org/dev/peps/pep-0307/ 2003) > This feature gives a false sense of security: nobody has ever done the necessary, extensive, code audit to prove that unpickling untrusted pickles cannot invoke unwanted code, and in fact bugs in the Python 2.2 pickle.py module make it easy to circumvent these security measures. > We firmly believe that, on the Internet, it is better to know that you are using an insecure protocol than to trust a protocol to be secure whose implementation hasn't been thoroughly checked. A few years ago, I think around 2016, there was a series of RCEs in many Java apps because they used the Java equivalent of pickle with the Java equivalent of "make pickle safe", which did not work.
- immibis 5y agoReminds me of the Java Applet exploit where you could combine system classes with overlapping method signatures in unexpected ways, to get the system to do untrusted things by itself without any user code. I bet __safe_for_unpickling__ has that problem. In the Java case, it was something like: create a listbox on the screen, which contains a map entry, whose value is a java.beans.Expression object which calls a getter on some object which has side effects that allow an RCE. Because only system code is involved in the chain, Java's stack-based security model determined that this was some internal runtime code making the call, and allowed it. It doesn't make sense to put a security check on any individual step, until the final one which determined it was running in a system context, yet the overall effect was something that should not have been allowed was allowed. The listbox innocently called toString() and what happened was RCE. I bet in Python you could use the same concept and construct an object graph where some innocent method call ends up being an RCE. Find an object whose str() calls self.foo.toString(), find an object whose toString() calls self.bar.blah(), find an object whose blah() calls self.asdf.meh(), find an object whose meh() calls os.system(self.cmd). Now you deserialize this graph and RCE is triggered by somebody trying to log the graph.