Control: tags 870187 + pending Dear maintainer,
I've prepared an NMU for supervisor (versioned as 3.3.1-1.1) and uploaded it to DELAYED/2. Please feel free to tell me if I should delay it longer. Regards, Salvatore
diff -Nru supervisor-3.3.1/debian/changelog supervisor-3.3.1/debian/changelog --- supervisor-3.3.1/debian/changelog 2016-09-07 15:47:05.000000000 +0200 +++ supervisor-3.3.1/debian/changelog 2017-08-12 10:55:14.000000000 +0200 @@ -1,3 +1,11 @@ +supervisor (3.3.1-1.1) unstable; urgency=medium + + * Non-maintainer upload. + * Disable object traversal in XML-RPC dispatch (CVE-2017-11610) + (Closes: #870187) + + -- Salvatore Bonaccorso <car...@debian.org> Sat, 12 Aug 2017 10:55:14 +0200 + supervisor (3.3.1-1) unstable; urgency=medium * New upstream release. diff -Nru supervisor-3.3.1/debian/patches/0001-Fix-CVE-2017-11610-by-disabling-object-traversal-in-.patch supervisor-3.3.1/debian/patches/0001-Fix-CVE-2017-11610-by-disabling-object-traversal-in-.patch --- supervisor-3.3.1/debian/patches/0001-Fix-CVE-2017-11610-by-disabling-object-traversal-in-.patch 1970-01-01 01:00:00.000000000 +0100 +++ supervisor-3.3.1/debian/patches/0001-Fix-CVE-2017-11610-by-disabling-object-traversal-in-.patch 2017-08-12 10:55:14.000000000 +0200 @@ -0,0 +1,166 @@ +From: Mike Naberezny <m...@naberezny.com> +Date: Mon, 24 Jul 2017 13:02:38 -0600 +Subject: Fix CVE-2017-11610 by disabling object traversal in XML-RPC dispatch +Origin: https://github.com/Supervisor/supervisor/commit/058f46141e346b18dee0497ba11203cb81ecb19e +Bug: https://github.com/Supervisor/supervisor/issues/964 +Bug-Debian: https://bugs.debian.org/870187 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2017-11610 + +--- + supervisor/tests/test_xmlrpc.py | 89 ++++++++++++++++++++++++++++++++++------- + supervisor/xmlrpc.py | 29 +++++++++----- + 2 files changed, 94 insertions(+), 24 deletions(-) + +diff --git a/supervisor/tests/test_xmlrpc.py b/supervisor/tests/test_xmlrpc.py +index 22042ad..856b5f9 100644 +--- a/supervisor/tests/test_xmlrpc.py ++++ b/supervisor/tests/test_xmlrpc.py +@@ -269,28 +269,89 @@ class XMLRPCHandlerTests(unittest.TestCase): + self.assertEqual(request._error, 500) + + class TraverseTests(unittest.TestCase): +- def test_underscore(self): ++ def test_security_disallows_underscore_methods(self): + from supervisor import xmlrpc +- self.assertRaises(xmlrpc.RPCError, xmlrpc.traverse, None, '_', None) ++ class Root: ++ pass ++ class A: ++ def _danger(self): ++ return True ++ root = Root() ++ root.a = A() ++ self.assertRaises(xmlrpc.RPCError, xmlrpc.traverse, ++ root, 'a._danger', []) ++ ++ def test_security_disallows_object_traversal(self): ++ from supervisor import xmlrpc ++ class Root: ++ pass ++ class A: ++ pass ++ class B: ++ def danger(self): ++ return True ++ root = Root() ++ root.a = A() ++ root.a.b = B() ++ self.assertRaises(xmlrpc.RPCError, xmlrpc.traverse, ++ root, 'a.b.danger', []) ++ ++ def test_namespace_name_not_found(self): ++ from supervisor import xmlrpc ++ class Root: ++ pass ++ root = Root() ++ self.assertRaises(xmlrpc.RPCError, xmlrpc.traverse, ++ root, 'notfound.hello', None) + +- def test_notfound(self): ++ def test_method_name_not_found(self): + from supervisor import xmlrpc +- self.assertRaises(xmlrpc.RPCError, xmlrpc.traverse, None, 'foo', None) ++ class Root: ++ pass ++ class A: ++ pass ++ root = Root() ++ root.a = A() ++ self.assertRaises(xmlrpc.RPCError, xmlrpc.traverse, ++ root, 'a.notfound', []) + +- def test_badparams(self): ++ def test_method_name_exists_but_is_not_a_method(self): + from supervisor import xmlrpc +- self.assertRaises(xmlrpc.RPCError, xmlrpc.traverse, self, +- 'test_badparams', (1, 2, 3)) ++ class Root: ++ pass ++ class A: ++ pass ++ class B: ++ pass ++ root = Root() ++ root.a = A() ++ root.a.b = B() ++ self.assertRaises(xmlrpc.RPCError, xmlrpc.traverse, ++ root, 'a.b', []) # b is not a method ++ ++ def test_bad_params(self): ++ from supervisor import xmlrpc ++ class Root: ++ pass ++ class A: ++ def hello(self, name): ++ return "Hello %s" % name ++ root = Root() ++ root.a = A() ++ self.assertRaises(xmlrpc.RPCError, xmlrpc.traverse, ++ root, 'a.hello', ["there", "extra"]) # too many params + + def test_success(self): + from supervisor import xmlrpc +- L = [] +- class Dummy: +- def foo(self, a): +- L.append(a) +- dummy = Dummy() +- xmlrpc.traverse(dummy, 'foo', [1]) +- self.assertEqual(L, [1]) ++ class Root: ++ pass ++ class A: ++ def hello(self, name): ++ return "Hello %s" % name ++ root = Root() ++ root.a = A() ++ result = xmlrpc.traverse(root, 'a.hello', ["there"]) ++ self.assertEqual(result, "Hello there") + + class SupervisorTransportTests(unittest.TestCase): + def _getTargetClass(self): +diff --git a/supervisor/xmlrpc.py b/supervisor/xmlrpc.py +index 339e19e..9a37c73 100644 +--- a/supervisor/xmlrpc.py ++++ b/supervisor/xmlrpc.py +@@ -428,18 +428,27 @@ class supervisor_xmlrpc_handler(xmlrpc_handler): + return traverse(self.rpcinterface, method, params) + + def traverse(ob, method, params): +- path = method.split('.') +- for name in path: +- if name.startswith('_'): +- # security (don't allow things that start with an underscore to +- # be called remotely) +- raise RPCError(Faults.UNKNOWN_METHOD) +- ob = getattr(ob, name, None) +- if ob is None: +- raise RPCError(Faults.UNKNOWN_METHOD) ++ dotted_parts = method.split('.') ++ # security (CVE-2017-11610, don't allow object traversal) ++ if len(dotted_parts) != 2: ++ raise RPCError(Faults.UNKNOWN_METHOD) ++ namespace, method = dotted_parts ++ ++ # security (don't allow methods that start with an underscore to ++ # be called remotely) ++ if method.startswith('_'): ++ raise RPCError(Faults.UNKNOWN_METHOD) ++ ++ rpcinterface = getattr(ob, namespace, None) ++ if rpcinterface is None: ++ raise RPCError(Faults.UNKNOWN_METHOD) ++ ++ func = getattr(rpcinterface, method, None) ++ if not isinstance(func, types.MethodType): ++ raise RPCError(Faults.UNKNOWN_METHOD) + + try: +- return ob(*params) ++ return func(*params) + except TypeError: + raise RPCError(Faults.INCORRECT_PARAMETERS) + +-- +2.14.1 + diff -Nru supervisor-3.3.1/debian/patches/series supervisor-3.3.1/debian/patches/series --- supervisor-3.3.1/debian/patches/series 1970-01-01 01:00:00.000000000 +0100 +++ supervisor-3.3.1/debian/patches/series 2017-08-12 10:55:14.000000000 +0200 @@ -0,0 +1 @@ +0001-Fix-CVE-2017-11610-by-disabling-object-traversal-in-.patch