Package: zope2.10 Severity: serious Tags: security patch -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Hi, Two vulnerabilities have been reported in Zope, which can be exploited by malicious people to bypass certain security restrictions and compromise a vulnerable system. 1) A missing access control check was found in the way Zope Enterprise Objects (ZEO) used to manage remote connections to the Zope server. A remote attacker could use this flaw to execute arbitrary Python code in the context of Zope server. (CVE-2009-0668)[0] 2) A weakness was found in the Zope Enterprise Objects (ZEO) authentication protocol. A remote attacker could use this flaw to bypass the authentication to the Zope Object Database (ZODB). (CVE-2009-0669)[1] If you fix the vulnerabilities please also make sure to include the CVE ids in your changelog entry. For further information see: [0] http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-0668 http://security-tracker.debian.net/tracker/CVE-2009-0668 [1] http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-0669 http://security-tracker.debian.net/tracker/CVE-2009-0669 http://mail.zope.org/pipermail/zope-announce/2009-August/002220.html Cheers, Giuseppe. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEARECAAYFAkp9N8EACgkQNxpp46476arVPQCeOfUT1sVlZUSXMETleD8pD+6A AA8AniYpFrHT9ERJ5UpgFXkcHkxgDIqF =UJsU -----END PGP SIGNATURE-----
=== StorageServer.py ================================================================== --- StorageServer.py (revision 167632) +++ StorageServer.py (local) @@ -111,7 +111,7 @@ for func in self.extensions: self._extensions[func.func_name] = None - def finish_auth(self, authenticated): + def _finish_auth(self, authenticated): if not self.auth_realm: return 1 self.authenticated = authenticated @@ -421,6 +421,7 @@ def new_oids(self, n=100): """Return a sequence of n new oids, where n defaults to 100""" + n = min(n, 100) if self.read_only: raise ReadOnlyError() if n <= 0: === auth/auth_digest.py ================================================================== --- auth/auth_digest.py (revision 167632) +++ auth/auth_digest.py (local) @@ -121,7 +121,7 @@ check = hexdigest("%s:%s" % (h_up, challenge)) if check == response: self.connection.setSessionKey(session_key(h_up, self._key_nonce)) - return self.finish_auth(check == response) + return self._finish_auth(check == response) extensions = [auth_get_challenge, auth_response] === tests/auth_plaintext.py ================================================================== --- tests/auth_plaintext.py (revision 167632) +++ tests/auth_plaintext.py (local) @@ -41,7 +41,7 @@ self.connection.setSessionKey(session_key(username, self.database.realm, password)) - return self.finish_auth(dbpw == password_dig) + return self._finish_auth(dbpw == password_dig) class PlaintextClient(Client): extensions = ["auth"] === zrpc/connection.py ================================================================== --- zrpc/connection.py (revision 167632) +++ zrpc/connection.py (local) @@ -24,7 +24,7 @@ import ThreadedAsync from ZEO.zrpc import smac from ZEO.zrpc.error import ZRPCError, DisconnectedError -from ZEO.zrpc.marshal import Marshaller +from ZEO.zrpc.marshal import Marshaller, ServerMarshaller from ZEO.zrpc.trigger import trigger from ZEO.zrpc.log import short_repr, log from ZODB.loglevels import BLATHER, TRACE @@ -883,6 +883,7 @@ def __init__(self, sock, addr, obj, mgr): self.mgr = mgr self.__super_init(sock, addr, obj, 'S') + self.marshal = ServerMarshaller() self.obj.notifyConnected(self) def handshake(self): === zrpc/marshal.py ================================================================== --- zrpc/marshal.py (revision 167632) +++ zrpc/marshal.py (local) @@ -52,6 +52,20 @@ level=logging.ERROR) raise +class ServerMarshaller(Marshaller): + + def decode(self, msg): + """Decodes msg and returns its parts""" + unpickler = cPickle.Unpickler(StringIO(msg)) + unpickler.find_global = server_find_global + + try: + return unpickler.load() # msgid, flags, name, args + except: + log("can't decode message: %s" % short_repr(msg), + level=logging.ERROR) + raise + _globals = globals() _silly = ('__doc__',) @@ -78,3 +92,21 @@ return r raise ZRPCError("Unsafe global: %s.%s" % (module, name)) + +def server_find_global(module, name): + """Helper for message unpickler""" + try: + m = __import__(module, _globals, _globals, _silly) + except ImportError, msg: + raise ZRPCError("import error %s: %s" % (module, msg)) + + try: + r = getattr(m, name) + except AttributeError: + raise ZRPCError("module %s has no global %s" % (module, name)) + + safe = getattr(r, '__no_side_effects__', 0) + if safe: + return r + + raise ZRPCError("Unsafe global: %s.%s" % (module, name))