Int/str conversions broken in latest Python bugfix releases

Our apologies for the lack of transparency in the process here. The issue was first reported to a number of other security teams, and converged in the Python Security Response Team where we agreed that the correct fix was to modify the runtime.

The delay between report and fix is entirely our fault. The security team is made up of volunteers, our availability isn’t always reliable, and there’s nobody “in charge” to coordinate work. We’ve been discussing how to improve our processes. However, we did agree that the potential for exploitation is high enough that we didn’t want to disclose the issue without a fix available and ready for use.

We did work through a number of alternative approaches, implementing many of them. The code doing int(gigabyte_long_untrusted_string) could be anywhere inside a json.load or HTTP header parser, and can run very deep. Parsing libraries are everywhere, and tend to use int indiscriminately (though they usually handle ValueError already). Expecting every library to add a new argument to every int() call would have led to thousands of vulnerabilities being filed, and made it impossible for users to ever trust that their systems could not be DoS’d.

We agree it’s a heavy hammer to do it in the core, but it’s also the only hammer that has a chance of giving users the confidence to keep running Python at the boundary of their apps.

Now, I’m personally inclined to agree that int->str conversions should do something other than raise. I was outvoted because it would break round-tripping, which is a reasonable argument that I accepted. We can still improve this over time and make it more usable. However, in most cases we saw, rendering an excessively long string isn’t desirable either. That should be the opt-in behaviour.

Raising an exception from str may prove to be too much, and could be reconsidered, but we don’t see a feasible way to push out updates to every user of int, so that will surely remain global.

4 Likes