Nov-02-2018, 07:39 PM
RE: http://bugs.jython.org/issue2454
We're using jython 2.2.1 and for a number of reasons can't upgrade, but I'm tasked with looking into this vulnerability. In looking over the fixes that were done, clearly the change to PyFunction.java is straightforward, but PyByteCode.java did not exist in 2.2.1 and I don't see comparable functionality. More importantly, it's not clear how to implement the tests given in 2.2.1. I've hacked my way through (given my limited experience with jython), and I've pretty much concluded that this vulnerability may not even apply to 2.2.1 given the apparent lack of Serializable support in general.
However, I'm happy to be proven wrong if someone can demonstrate how to convert the tests to equivalent functionality in 2.2.1. The two tests in question are:
The harder one to convert is:
The summary is:
(1) does the vulnerability even exist in 2.2.1?
(2) how can I fix the tests to test for it?
I'd appreciate any insight anyone has to offer here.
Thanks,
Jim Gish
We're using jython 2.2.1 and for a number of reasons can't upgrade, but I'm tasked with looking into this vulnerability. In looking over the fixes that were done, clearly the change to PyFunction.java is straightforward, but PyByteCode.java did not exist in 2.2.1 and I don't see comparable functionality. More importantly, it's not clear how to implement the tests given in 2.2.1. I've hacked my way through (given my limited experience with jython), and I've pretty much concluded that this vulnerability may not even apply to 2.2.1 given the apparent lack of Serializable support in general.
However, I'm happy to be proven wrong if someone can demonstrate how to convert the tests to equivalent functionality in 2.2.1. The two tests in question are:
def test_java_serialization_pycode(self): def universal_answer(): return 42 serialized_code = roundtrip_serialization(universal_answer.func_code) self.assertEqual(eval(serialized_code), universal_answer())This one throws NotSerializableException on org.python.pycode._pyx0 (based on some instrumentation, this appears to be caused by PyFunctionTable not being serializable)
The harder one to convert is:
def test_java_serialization_pyfunction(self): # Not directly supported due to lack of general utility # (globals will usually be in the function object in # func_globals), and problems with unserialization # vulnerabilities. Users can always subclass from PyFunction # for specific cases, as seen in PyCascading import new def f(): return 6 * 7 + max(0, 1, 2) # However, using the new module, it's possible to create a # function with no globals, which means the globals will come # from the current context g = new.function(f.func_code, {}, "g") # But still forbid Java deserialization of this function # object. Use pickling or other support instead. with self.assertRaises(UnsupportedOperationException): roundtrip_serialization(g)My best approximation in 2.2.1 is:
def test_java_serialization_pyfunction(self): # Not directly supported due to lack of general utility # (globals will usually be in the function object in # func_globals), and problems with unserialization # vulnerabilities. Users can always subclass from PyFunction # for specific cases, as seen in PyCascading def f(): return 6 * 7 + max(0, 1, 2) # However, using the new module, it's possible to create a # function with no globals, which means the globals will come # from the current context import types # globals, defaults, code g = types.FunctionType(None, None, f.func_code) # But still forbid Java deserialization of this function # object. Use pickling or other support instead. try: roundtrip_serialization(g) except UnsupportedOperationException: return # expected. passes except: exctype, value = sys.exc_info()[:2] print "\nAn exception of type "+str(exctype)+" occurred.\n" # traceback.print_stack() assert False, "serialization failed with wrong exception" assert False, "serialization succeeded, but shouldn't have"However, this one is also getting NotSerializableException and not even getting to the readResolve in PyFunction that now throws UnsupportedOperationException.
The summary is:
(1) does the vulnerability even exist in 2.2.1?
(2) how can I fix the tests to test for it?
I'd appreciate any insight anyone has to offer here.
Thanks,
Jim Gish