2.7.3 beta attribute permission problems
Hi all, I've instal·led Zope 2.7.3b2 (python 2.3.4, gnu/linux box) to test my products and at the first moment I've found a terrible problem for me. My applications began to raise "Unauthorized: The container has no security assertions" errors everywhere. I've been looking for in google and found this thread: http://www.mail-archive.com/zope-dev%40zope.org/msg17218.html Really the problem seems to be exactly the same. A simple example: I have a persistent object A and a non persistent object B. B has implicit acquisition. From trusted code I return B.__of__(A). Trying to access B.meta_type from untrusted code (a ZPT) raises the error. B has no attribute meta_type, so it should be returned from A using implicit acquisition. A has all necessary security assertions. All this has been working fine from Zope 2.7.0 to 2.7.2. The problem appears the first time in Zope 2.7.3 beta. As Richard Jones says, the problem seems to be a little change in AccessControl/ImplPython.py: 554,557d553 < # Filter out the objects we can't access. < if hasattr(inst, 'aq_acquire'): < return inst.aq_acquire(name, aq_validate, validate) < # Or just try to get the attribute directly. and I think also in cAccessControl.c: 2112,2123d2113 < # Filter out the objects we can't access. < if hasattr(inst, 'aq_acquire'): < return inst.aq_acquire(name, aq_validate, validate) < */ < if (aq_isWrapper(inst)) < { < Py_DECREF(v); < return aq_Acquire(inst, name, aq_validate, validate, 1, NULL, 0); < } < < /* < # Or just try to get the attribute directly. Thanks in advance Santi Camps http://www.earcon.com
Santi Camps wrote at 2004-10-18 12:37 +0200:
... I have a persistent object A and a non persistent object B. B has implicit acquisition. From trusted code I return B.__of__(A). Trying to access B.meta_type from untrusted code (a ZPT) raises the error. B has no attribute meta_type, so it should be returned from A using implicit acquisition. A has all necessary security assertions.
"meta_type" is probably a string. Elementary data types (such as string) do not know anything about acquisition. The code that checks the permissions cannot (easily) determine where it comes from (other than reimplementing acquisition, which would not be a good thing). -- Dieter
En/na Dieter Maurer ha escrit:
Santi Camps wrote at 2004-10-18 12:37 +0200:
... I have a persistent object A and a non persistent object B. B has implicit acquisition. From trusted code I return B.__of__(A). Trying to access B.meta_type from untrusted code (a ZPT) raises the error. B has no attribute meta_type, so it should be returned from A using implicit acquisition. A has all necessary security assertions.
"meta_type" is probably a string. Elementary data types (such as string) do not know anything about acquisition. The code that checks the permissions cannot (easily) determine where it comes from (other than reimplementing acquisition, which would not be a good thing).
Yes, meta_type is an attribute of type string, but I don't understand your reasons. Acquisition, obviously, is not implemented in strings, but if the object containing meta_type attribute inherits from Acquisition.Implicit it should work. In fact, it works for Zope 2.7.0 to 2.7.2. The problem appears in Zope 2.7.3, and I think that the problem is the change I mentioned in AccessControl/cAccessControl.c and AccessControl/ImplPython.py. I suppose this change is for some reasonable reason, but if it breaks security validations throught implicit acqusition I think the change should be considered. Regards Santi Camps http://www.earcon.com
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 19/10/2004, at 4:33 PM, Santi Camps wrote:
Yes, meta_type is an attribute of type string, but I don't understand your reasons. Acquisition, obviously, is not implemented in strings, but if the object containing meta_type attribute inherits from Acquisition.Implicit it should work. In fact, it works for Zope 2.7.0 to 2.7.2. The problem appears in Zope 2.7.3, and I think that the problem is the change I mentioned in AccessControl/cAccessControl.c and AccessControl/ImplPython.py. I suppose this change is for some reasonable reason, but if it breaks security validations throught implicit acqusition I think the change should be considered.
AFAIK Tres is working on this. I was unable to produce a simple example case, but more recently Stefan Holek (I think) was. The last I saw was Tres saying "Aargh!" on the 13th, then on the 14th saying he's unable to produce good test cases. And that's the problem. Tres' patch removed "DWIM" code. I'm not sure what that meant (I know what DWIM stands for ;) ... and I'm unable to state exactly (in a test case) what it is that my code does that invokes the DWIM'y code. Richard -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.4 (Darwin) iD8DBQFBdLffrGisBEHG6TARAlEZAJ46betsryQklXpFxPFK1EuxozGZxwCghtGG +XdZTjWsgdahMh6qqGrwPL4= =v/LZ -----END PGP SIGNATURE-----
En/na Richard Jones ha escrit:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 19/10/2004, at 4:33 PM, Santi Camps wrote:
Yes, meta_type is an attribute of type string, but I don't understand your reasons. Acquisition, obviously, is not implemented in strings, but if the object containing meta_type attribute inherits from Acquisition.Implicit it should work. In fact, it works for Zope 2.7.0 to 2.7.2. The problem appears in Zope 2.7.3, and I think that the problem is the change I mentioned in AccessControl/cAccessControl.c and AccessControl/ImplPython.py. I suppose this change is for some reasonable reason, but if it breaks security validations throught implicit acqusition I think the change should be considered.
AFAIK Tres is working on this. I was unable to produce a simple example case, but more recently Stefan Holek (I think) was. The last I saw was Tres saying "Aargh!" on the 13th, then on the 14th saying he's unable to produce good test cases.
And that's the problem. Tres' patch removed "DWIM" code. I'm not sure what that meant (I know what DWIM stands for ;) ... and I'm unable to state exactly (in a test case) what it is that my code does that invokes the DWIM'y code.
Richard
Thanks very much for the information, Richard. I think I should be able to provide a good test code (all our framework crash in zope 2.7.3 due to this patch). Let's go Santi Camps http://www.earcon.com
En/na Santi Camps ha escrit:
En/na Richard Jones ha escrit:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 19/10/2004, at 4:33 PM, Santi Camps wrote:
Yes, meta_type is an attribute of type string, but I don't understand your reasons. Acquisition, obviously, is not implemented in strings, but if the object containing meta_type attribute inherits from Acquisition.Implicit it should work. In fact, it works for Zope 2.7.0 to 2.7.2. The problem appears in Zope 2.7.3, and I think that the problem is the change I mentioned in AccessControl/cAccessControl.c and AccessControl/ImplPython.py. I suppose this change is for some reasonable reason, but if it breaks security validations throught implicit acqusition I think the change should be considered.
AFAIK Tres is working on this. I was unable to produce a simple example case, but more recently Stefan Holek (I think) was. The last I saw was Tres saying "Aargh!" on the 13th, then on the 14th saying he's unable to produce good test cases.
And that's the problem. Tres' patch removed "DWIM" code. I'm not sure what that meant (I know what DWIM stands for ;) ... and I'm unable to state exactly (in a test case) what it is that my code does that invokes the DWIM'y code.
Richard
Thanks very much for the information, Richard. I think I should be able to provide a good test code (all our framework crash in zope 2.7.3 due to this patch). Let's go
Santi Camps http://www.earcon.com
Here you are a test case for that problem. It's a very simple case of what my framework does. How to proceed: 1) Install the product in a Zope 2.7.3 beta 2) Add an instance of meta type "AccessControl Test" 3) Try http://localhost:8080/AccessControlTest/get_sum_of_values. It works fine (is a method of Test class) 4) Try http://localhost:8080/AccessControlTest/get_product_of_values. It also works fine (is a method of Adapter class) 5) Try http://localhost:8080/AccessControlTest/crashing_test (is a ZPT trying to access previous methods). It crashes !! * Error Type: Unauthorized* *Error Value: The container has no security assertions. Access to 'get_sum_of_values' of (Adapter instance at 40ae6ac0) denied.* Obviously, this is not a reasonable behaviour. If I can access those methods directly from an URL, I should be able to do it from a ZPT. Doing the same on Zope 2.7.2 works fine. I hope this help Santi Camps http://www.earcon.com
Santi Camps wrote:
Here you are a test case for that problem. It's a very simple case of what my framework does.
How to proceed: 1) Install the product in a Zope 2.7.3 beta 2) Add an instance of meta type "AccessControl Test" 3) Try http://localhost:8080/AccessControlTest/get_sum_of_values. It works fine (is a method of Test class) 4) Try http://localhost:8080/AccessControlTest/get_product_of_values. It also works fine (is a method of Adapter class) 5) Try http://localhost:8080/AccessControlTest/crashing_test (is a ZPT trying to access previous methods). It crashes !! * Error Type: Unauthorized* *Error Value: The container has no security assertions Access to 'get_sum_of_values' of (Adapter instance at 40ae6ac0) denied.*
Obviously, this is not a reasonable behaviour. If I can access those methods directly from an URL, I should be able to do it from a ZPT.
Doing the same on Zope 2.7.2 works fine.
To make this a useful test case, I need the product which implements the "AccessControl Test" objects. Even better would be able to reproduce the behviour using a minimal "dummy" class. Tres. -- =============================================================== Tres Seaver tseaver@zope.com Zope Corporation "Zope Dealers" http://www.zope.com
Santi Camps wrote at 2004-10-19 15:05 +0200:
... Error Type: Unauthorized* *Error Value: The container has no security assertions. Access to 'get_sum_of_values' of (Adapter instance at 40ae6ac0) denied.*
This tells you that the container containing "get_sum_of_values" does not have security assertions. Is this wrong? -- Dieter
Dieter Maurer wrote:
Santi Camps wrote at 2004-10-19 15:05 +0200:
... Error Type: Unauthorized* *Error Value: The container has no security assertions. Access to 'get_sum_of_values' of (Adapter instance at 40ae6ac0) denied.*
This tells you that the container containing "get_sum_of_values" does not have security assertions. Is this wrong?
The container (the class Test.Test in Santi'a product) does have security assertions for *itself*: class Test(OrderedFolder): """ Test """ meta_type = 'AccessControl Test' security = ClassSecurityInfo() security.declareObjectProtected('View') However it makes no assertion for the attribute 'get_sum_of_values': ############################################################ def get_sum_of_values(self): """ """ return self.value1 + self.value2 AFAICT, the new behavior is perfectly correct here: absent either an explicit permisison declaration for 'get_sum_of_values', or a "blanket grant" for unprotected subobjects (e.g, 'security.setDefaultAccess(1)'), the template which fails *should* fail; the fact that it used to succeed was merely a security hole. Tres. -- =============================================================== Tres Seaver tseaver@zope.com Zope Corporation "Zope Dealers" http://www.zope.com
En/na Tres Seaver ha escrit:
Dieter Maurer wrote:
Santi Camps wrote at 2004-10-19 15:05 +0200:
... Error Type: Unauthorized* *Error Value: The container has no security assertions. Access to 'get_sum_of_values' of (Adapter instance at 40ae6ac0) denied.*
This tells you that the container containing "get_sum_of_values" does not have security assertions. Is this wrong?
The container (the class Test.Test in Santi'a product) does have security assertions for *itself*:
class Test(OrderedFolder): """ Test """
meta_type = 'AccessControl Test'
security = ClassSecurityInfo() security.declareObjectProtected('View')
However it makes no assertion for the attribute 'get_sum_of_values':
############################################################ def get_sum_of_values(self): """ """ return self.value1 + self.value2
AFAICT, the new behavior is perfectly correct here: absent either an explicit permisison declaration for 'get_sum_of_values', or a "blanket grant" for unprotected subobjects (e.g, 'security.setDefaultAccess(1)'), the template which fails *should* fail; the fact that it used to succeed was merely a security hole.
Tres.
Hi again, Adding a security.declareProtected('View', 'get_sum_of_values') results in the same error. Anyway, I can't understand a behaviour that allows to access a method directly from the URL and crashes when the access is done from a ZPT. If what you want to do is that all methods without explicit permission declaration be considered private, direct access from an URL should also raise an Unauthorized error, I think. On the other hand, I don't think that current code could be considered a security hole. If a method is unprotected, then the protection of the object itself is applied. I like it. But I understand that this is a personal opinion. I supose the change is due to some security hole found. Regards Santi Camps http://www.earcon.com
Santi Camps wrote at 2004-10-20 07:18 +0200:
... Anyway, I can't understand a behaviour that allows to access a method directly from the URL and crashes when the access is done from a ZPT.
"ZPublisher" (more precisely: "ZPublisher.BaseRequest.BaseRequest.traverse") is responsible for security checking for Web traversal. It uses a different approach then "AccessControl" (which protects access from restricted code). As you found out: Tres fixed a security whole in "AccessControl" but a similar whole is still present in "ZPublisher"...
... On the other hand, I don't think that current code could be considered a security hole. If a method is unprotected, then the protection of the object itself is applied. I like it.
But the names chosen to control this behaviour ("__allow_access_to_unprotected_subobjects__") suggests that this should not apply automatically. -- Dieter
participants (4)
-
Dieter Maurer -
Richard Jones -
Santi Camps -
Tres Seaver