Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Subtle problem with introduction of new PermissionProxy #3

Open
tseaver opened this issue Jan 24, 2015 · 0 comments
Open

Subtle problem with introduction of new PermissionProxy #3

tseaver opened this issue Jan 24, 2015 · 0 comments
Labels

Comments

@tseaver
Copy link
Member

tseaver commented Jan 24, 2015

In https://bugs.launchpad.net/zope.security/+bug/98190, Garrett Smith reported:

This is subtle problem, and a little hard to explain. I've included a sample view + ZCML to illustrate -- see below.

The problem comes up when you have a view that implements IBrowserPublisher and returns itself in browserDefault (see sample below).

The code that looks up browserDefault is in zope\app\publication\browser.py starting at line 56:

    if IBrowserPublisher.providedBy(ob):
        # ob is already proxied, so the result of ...
        return ob.browserDefault(request)

When PermissionProxy is used, ob is a correctly security-proxied PermissionProxy instance. The permissions on ob work as expected.

When ob returns itself in browserDefault, however, it returns a security-proxied version of the base object -- not the permission proxy that owns the __Security_checker__. Because __Security_checker__ isn't available, the security proxy uses whatever checker is registered for the view type. In the case where zope:view is used to register a view (see sample zcml below), there will be no checker -- and the security proxy returned by browserDefault will be entirely forbidden.

This problem didn't occur before because proxify either modified the utility's __Security_checker__ directly, or created a security proxy outright.

This may not actually be a 'bug', but it's very subtle behavior -- and hard to track down if you run into it. There are a couple work-arounds in ZCML:

  • Declare permissions for the view class
  • Use the zope:adapter directive to register the view
# test.py 
from zope.interface import Interface, Attribute, implements
from zope.publisher.interfaces.browser import IBrowserPublisher

from zope.app.traversing.interfaces import TraversalError

class ISampleView(IBrowserPublisher):

    foo = Attribute("Sample attr.")

class SampleView(object):

    implements(ISampleView)

    def __init__(self, context, request):
        self.context = context
        self.request = request
        self.foo = 'Foo'

    def browserDefault(self, request):
        return self, ()

    def publishTraverse(self, request, name):
        raise TraversalError(self, name, request)

    def __call__(self):
        return self.foo
<!-- test-configure.zcml -->
<configure xmlns="http:https://namespaces.zope.org/zope" i18n_domain="test">

  <view
    name="test"
    type="zope.publisher.interfaces.browser.IBrowserRequest"
    for="*"
    provides="test.ISampleView"
    factory="test.SampleView"
    permission="zope.Public"
    allowed_interface="test.ISampleView" />

</configure>
@tseaver tseaver added the bug label Jan 24, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant