Package: zope3
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)

iEYEARECAAYFAkp9NrUACgkQNxpp46476arpRgCfRoRAXrXRFh3e74TxS//3rSGF
xZIAn3i3/BbFZV0maWR0meELgaKlDXZ9
=G1ST
-----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))

Reply via email to