DSM

NAVIGATION
CATEGORIES
REFERRENCE
LINKS
  • External Methods, Proxy Roles, and Executable Security

    9 answers - 2604 bytes - related search similar search Add To My Delicious Add To My Stumble Upon Add To My Google Mark Add To My Facebook Add To My Digg Add To My Reddit

    In CMFCore 1.5.4:
    If a low-security-clearance user calls an external method that pastes
    an object from a PortalFolder, he gets an error because the following
    line in CMFCore.PortalFolder fails:
    if not sm.checkPermission(D, parent):
    raise AccessControl_Unauthorized
    This is even the case if "sm.checkPermission" is changed to
    "_checkPermission", which takes into account proxy roles. The external
    method does not allow proxy roles attached, so I can't just add a
    "Manager" proxy role.
    Because I called the pasting in an external method, I expected it to
    go through without security problems! Is this a right expectation /
    and a bug, or a wrong expectation?
    Peace,
    George
    11/18/05, George Lee <georgeleejr (AT) gmail (DOT) comwrote:
    I forget if I submitted a collector issue about this before, but I
    didn't see it. I just posted one at
    <>:
    Title: PortalFolder.py Paste ignores executable security
    Version info: CMF 1.5.4 but also in trunk
    Paste calls "sm.checkPermission(permission_name,self)"
    rather than "_checkPermission(permission_name,self)"
    This makes it ignore executable security. So, if Paste is
    in an external method or in a script with sufficient proxy roles, it
    raises an Unauthorized error for users when the external method /
    proxy role security should suffice.
    >
    >
    >

    9/9/05, Dieter Maurer <dieter (AT) handshake (DOT) dewrote:
    George Lee wrote at 2005-9-8 23:57 -0400:

    >Is it okay to just replace sm.checkPermission with _checkPermission
    >from CMFCore.utils or is that not okay?
    >

    Yes. But, please file a bug report as well.
    >
    >Also Dieter I noticed that Alan Runyan and you briefly discussed this
    >issue back in 2002:
    >
    >

    Any internal use should always take executable security (i.e.
    executable ownership and proxy roles) into account.
    Not doing so is a but, as things expected to be possible are not
    and (maybe even worse) things expected to be impossible may
    be possible.
    There may be a need for application code to check the permissions
    of the user with proxy roles not taken into account.
    E.g. a script that must use a "Manager" roles to do one
    thing but does not want to do another unless the current
    user has specific permissions.
    For this case, there also should be a method checking
    permissions with proxy roles not taken into account.
  • No.1 | | 2876 bytes | |

    p.s. This is in the context of a external method in a workflow scripts
    folder, if that helps.

    Peace,
    George

    11/19/05, George Lee <georgeleejr (AT) gmail (DOT) comwrote:
    In CMFCore 1.5.4:

    If a low-security-clearance user calls an external method that pastes
    an object from a PortalFolder, he gets an error because the following
    line in CMFCore.PortalFolder fails:

    if not sm.checkPermission(D, parent):
    raise AccessControl_Unauthorized

    This is even the case if "sm.checkPermission" is changed to
    "_checkPermission", which takes into account proxy roles. The external
    method does not allow proxy roles attached, so I can't just add a
    "Manager" proxy role.

    Because I called the pasting in an external method, I expected it to
    go through without security problems! Is this a right expectation /
    and a bug, or a wrong expectation?

    Peace,
    George
    >
    >
    >
    >
    >
    >
    >

    11/18/05, George Lee <georgeleejr (AT) gmail (DOT) comwrote:
    I forget if I submitted a collector issue about this before, but I
    didn't see it. I just posted one at
    <>:

    Title: PortalFolder.py Paste ignores executable security

    Version info: CMF 1.5.4 but also in trunk

    Paste calls "sm.checkPermission(permission_name,self)"
    rather than "_checkPermission(permission_name,self)"

    This makes it ignore executable security. So, if Paste is
    in an external method or in a script with sufficient proxy roles, it
    raises an Unauthorized error for users when the external method /
    proxy role security should suffice.
    >
    >
    >

    9/9/05, Dieter Maurer <dieter (AT) handshake (DOT) dewrote:
    George Lee wrote at 2005-9-8 23:57 -0400:

    >Is it okay to just replace sm.checkPermission with _checkPermission
    >from CMFCore.utils or is that not okay?
    >

    Yes. But, please file a bug report as well.
    >
    >Also Dieter I noticed that Alan Runyan and you briefly discussed this
    >issue back in 2002:
    >
    >

    Any internal use should always take executable security (i.e.
    executable ownership and proxy roles) into account.
    Not doing so is a but, as things expected to be possible are not
    and (maybe even worse) things expected to be impossible may
    be possible.

    There may be a need for application code to check the permissions
    of the user with proxy roles not taken into account.

    E.g. a script that must use a "Manager" roles to do one
    thing but does not want to do another unless the current
    user has specific permissions.

    For this case, there also should be a method checking
    permissions with proxy roles not taken into account.
  • No.2 | | 3524 bytes | |

    George Lee wrote at 2005-11-19 00:46 -0500:
    >In CMFCore 1.5.4:
    >
    >If a low-security-clearance user calls an external method that pastes
    >an object from a PortalFolder, he gets an error because the following
    >line in CMFCore.PortalFolder fails:
    >
    >if not sm.checkPermission(D, parent):

    raise AccessControl_Unauthorized
    >
    >This is even the case if "sm.checkPermission" is changed to
    >"_checkPermission", which takes into account proxy roles. The external
    >method does not allow proxy roles attached, so I can't just add a
    >"Manager" proxy role.
    >
    >Because I called the pasting in an external method, I expected it to
    >go through without security problems! Is this a right expectation /
    >and a bug, or a wrong expectation?


    It is the fate induced by explicit security checks.
    It will get much worse when the Zope 3 security comes into
    Zope 2 land: then even trusted code will have to deal with
    security proxied objects.

    We currently work around the problem that trusted code
    cannot have proxy roles with the following class:

    class ProxyContext:
    def __init__(self, proxy_roles):
    self._proxy_roles = tuple(proxy_roles)

    def (self): return None
    getW =

    This class emulates an object with proxy roles and can be pushed
    onto the "SecurityManager"s "context" stack like so:

    sm = getSecurityManager()
    context = ProxyContext(proxy_roles)
    sm.addContext(context)
    try:
    # do something with "proxy_roles"

    finally: sm.removeContext(context)

    Note, that I had to fix (in a local copy) CMF's "_checkPermission"
    for this to work:

    It had decided to emulate Zope's proxy role checking only
    approximately -- incorrectly for a "None" owner.

    My fix looks like this:

    security.declarePrivate('_checkPermission')
    def _checkPermission(permission, obj):
    """ Check if the current user has the permission on the given object.
    """
    # this code is ported from
    roles = rolesForP(permission, obj)
    if isinstance(roles, basestring):
    roles = [roles]
    context = getSecurityManager()._context

    # check executable owner and proxy roles
    # this code is ported from ZopeSecurityPolicy.validate
    stack = context.stack
    if stack:
    eo = stack[-1]
    owner = ()
    if owner is not None:
    if not owner.allowed(obj, roles):
    return 0
    # DM 2005-09-07: no reason to do it differently from Zope
    # It accepts "proxy_roles" even for a None owner
    ## proxy_roles = getattr(eo, '_proxy_roles', None)
    ## if proxy_roles:
    ## if obj is not aq_base(obj):
    ## if not owner._check_context(obj):
    ## return 0
    ## for r in proxy_roles:
    ## if r in roles:
    ## return 1
    ## return 0
    proxy_roles = getattr(eo, '_proxy_roles', None)
    if proxy_roles:
    if obj is not aq_base(obj):
    # DM 2005-09-07: do it as Zope does
    #if not owner._check_context(obj):
    if owner is not None and not owner._check_context(obj):
    return 0
    for r in proxy_roles:
    if r in roles:
    return 1
    return 0

    return context.user.allowed(obj, roles)

    If you are interested in using this approach, you
    should probably file another CMF bug report about the
    wrong handling of proxy roles in "_checkPermission".
    I explicitely allow you to attach the fix given above.
  • No.3 | | 3919 bytes | |

    Great, thanks much.

    Is there much buzz about this in CMF developer land? It seems like
    proper proxy roles handling, and like you said what Zope 3 security
    will do to it, are pretty important and will come up quite often (all
    I was doing, after all, was trying to move an object upon workflow
    change!).

    Peace,
    George

    11/19/05, Dieter Maurer <dieter (AT) handshake (DOT) dewrote:
    George Lee wrote at 2005-11-19 00:46 -0500:
    >In CMFCore 1.5.4:
    >
    >If a low-security-clearance user calls an external method that pastes
    >an object from a PortalFolder, he gets an error because the following
    >line in CMFCore.PortalFolder fails:
    >
    >if not sm.checkPermission(D, parent):

    raise AccessControl_Unauthorized
    >
    >This is even the case if "sm.checkPermission" is changed to
    >"_checkPermission", which takes into account proxy roles. The external
    >method does not allow proxy roles attached, so I can't just add a
    >"Manager" proxy role.
    >
    >Because I called the pasting in an external method, I expected it to
    >go through without security problems! Is this a right expectation /
    >and a bug, or a wrong expectation?
    >

    It is the fate induced by explicit security checks.
    It will get much worse when the Zope 3 security comes into
    Zope 2 land: then even trusted code will have to deal with
    security proxied objects.
    --
    We currently work around the problem that trusted code
    cannot have proxy roles with the following class:

    class ProxyContext:
    def __init__(self, proxy_roles):
    self._proxy_roles = tuple(proxy_roles)

    def (self): return None
    getW =

    This class emulates an object with proxy roles and can be pushed
    onto the "SecurityManager"s "context" stack like so:

    sm = getSecurityManager()
    context = ProxyContext(proxy_roles)
    sm.addContext(context)
    try:
    # do something with "proxy_roles"

    finally: sm.removeContext(context)
    --
    Note, that I had to fix (in a local copy) CMF's "_checkPermission"
    for this to work:

    It had decided to emulate Zope's proxy role checking only
    approximately -- incorrectly for a "None" owner.

    My fix looks like this:

    security.declarePrivate('_checkPermission')
    def _checkPermission(permission, obj):
    """ Check if the current user has the permission on the given object.
    """
    # this code is ported from
    roles = rolesForP(permission, obj)
    if isinstance(roles, basestring):
    roles = [roles]
    context = getSecurityManager()._context

    # check executable owner and proxy roles
    # this code is ported from ZopeSecurityPolicy.validate
    stack = context.stack
    if stack:
    eo = stack[-1]
    owner = ()
    if owner is not None:
    if not owner.allowed(obj, roles):
    return 0
    # DM 2005-09-07: no reason to do it differently from Zope
    # It accepts "proxy_roles" even for a None owner
    ## proxy_roles = getattr(eo, '_proxy_roles', None)
    ## if proxy_roles:
    ## if obj is not aq_base(obj):
    ## if not owner._check_context(obj):
    ## return 0
    ## for r in proxy_roles:
    ## if r in roles:
    ## return 1
    ## return 0
    proxy_roles = getattr(eo, '_proxy_roles', None)
    if proxy_roles:
    if obj is not aq_base(obj):
    # DM 2005-09-07: do it as Zope does
    #if not owner._check_context(obj):
    if owner is not None and not owner._check_context(obj):
    return 0
    for r in proxy_roles:
    if r in roles:
    return 1
    return 0

    return context.user.allowed(obj, roles)
    --
    If you are interested in using this approach, you
    should probably file another CMF bug report about the
    wrong handling of proxy roles in "_checkPermission".
    I explicitely allow you to attach the fix given above.
    --
  • No.4 | | 949 bytes | |

    20 Nov 2005, at 18:47, George Lee wrote:

    Great, thanks much.

    Is there much buzz about this in CMF developer land? It seems like
    proper proxy roles handling, and like you said what Zope 3 security
    will do to it, are pretty important and will come up quite often (all
    I was doing, after all, was trying to move an object upon workflow
    change!).

    IMH proxy roles should be used extremely sparingly, if at all. They
    are a last resort and I personally never use them. Matter of fact I
    believe having to use them means the application design could use
    some improvement

    If something needs to be done with elevated privileges it should be
    in filesystem product code or, if that is not feasible, in an
    external method. At least that's my philosophy ;)

    jens

    Zope maillist - Zope (AT) zope (DOT) org

    ** No cross posts or HTML encoding! **
    (Related lists -

    )
  • No.5 | | 250 bytes | |

    George Lee wrote at 2005-11-20 12:47 -0500:
    >Is there much buzz about this in CMF developer land?

    Apart from regular problem reports (usually in the Plone mailing list),
    there are few talks about proxy roles.
  • No.6 | | 1215 bytes | |

    Jens Vagelpohl wrote at 2005-11-20 19:01 +0100:

    >IMH proxy roles should be used extremely sparingly, if at all. They
    >are a last resort and I personally never use them. Matter of fact I
    >believe having to use them means the application design could use
    >some improvement
    >
    >If something needs to be done with elevated privileges it should be
    >in filesystem product code or, if that is not feasible, in an
    >external method. At least that's my philosophy ;)


    You have lost the thread's start:

    George's problem has been that he could not move an object
    in an *EXTERNAL METHD*, i.e. in trusted filesystem code.

    He would have the same problem in a filesystem product.

    The problem is that "CopySupport" performs a local security
    check (in "Paste") independent from its caller
    (it does not matter whether the rename/move/copy was
    called from trusted or untrusted code).

    With appropriate proxy roles, an untrusted Python Script can perform some
    rename/move/copy that trusted code is unable to perform.

    I assume you can agree that this is a somewhat unsane situation
  • No.7 | | 943 bytes | |

    22 Nov 2005, at 20:08, Dieter Maurer wrote:
    You have lost the thread's start:

    George's problem has been that he could not move an object
    in an *EXTERNAL METHD*, i.e. in trusted filesystem code.

    He would have the same problem in a filesystem product.

    The problem is that "CopySupport" performs a local security
    check (in "Paste") independent from its caller
    (it does not matter whether the rename/move/copy was
    called from trusted or untrusted code).

    With appropriate proxy roles, an untrusted Python Script can
    perform some
    rename/move/copy that trusted code is unable to perform.

    I assume you can agree that this is a somewhat unsane situation

    Yes, that's very odd thanks for reminding me of the thread's start!

    jens

    Zope maillist - Zope (AT) zope (DOT) org

    ** No cross posts or HTML encoding! **
    (Related lists -

    )
  • No.8 | | 2078 bytes | |

    PGP SIGNED MESSAGE
    Hash: SHA1

    Jens Vagelpohl wrote:

    22 Nov 2005, at 20:08, Dieter Maurer wrote:

    >You have lost the thread's start:
    >>

    >George's problem has been that he could not move an object
    >in an *EXTERNAL METHD*, i.e. in trusted filesystem code.
    >>

    >He would have the same problem in a filesystem product.
    >>

    >The problem is that "CopySupport" performs a local security
    >check (in "Paste") independent from its caller
    >(it does not matter whether the rename/move/copy was
    >called from trusted or untrusted code).
    >>

    >With appropriate proxy roles, an untrusted Python Script can
    >perform some
    >rename/move/copy that trusted code is unable to perform.
    >>

    >I assume you can agree that this is a somewhat unsane situation


    Yes, that's very odd thanks for reminding me of the thread's start!

    The actual problem here is a confusion of "authorization" with
    "containment constraints": the CopySupport code is using a single check
    to test both, which makes it impossible to do the Right Thing (TM):
    either the proxy roles should be taken into account, in which case the
    containment constraint may be violated, or they shouldn't, in which case
    a proxy-role-granted script cannot be used to perform a "controlled"
    paste which would otherwise not be authorized.

    Tres.
    - --
    Tres Seaver +1 202-558-7113 tseaver (AT) palladion (DOT) com
    Palladion Software "Excellence by Design" http://palladion.com
    PGP SIGNATURE
    Version: GnuPG v1.4.1 (GNU/Linux)
    Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

    kWErhWp0Zm95oGrNK+6o=
    =Thwe
    PGP SIGNATURE

    Zope maillist - Zope (AT) zope (DOT) org

    ** No cross posts or HTML encoding! **
    (Related lists -

    )
  • No.9 | | 1300 bytes | |

    Tres Seaver wrote at 2005-11-22 16:51 -0500:

    >The actual problem here is a confusion of "authorization" with
    >"containment constraints": the CopySupport code is using a single check
    >to test both, which makes it impossible to do the Right Thing (TM):
    >either the proxy roles should be taken into account, in which case the
    >containment constraint may be violated, or they shouldn't, in which case
    >a proxy-role-granted script cannot be used to perform a "controlled"
    >paste which would otherwise not be authorized.


    Not sure that I follow you:

    In my view, "all_meta_types" can be used to enforce
    "containment constraints". "CopySupport" handles this
    it a perfect fashion.

    After this "containment constraints" check, it
    checks that the copying/moving/renaming user has the
    right to add the object in the destination folder
    (it fact, it checks that the creating action can be traversed to,
    which is a bit different and fails when the action contains a
    query string).
    Modern versions take proxy roles into account.

    The problem is that trusted code lacks a means to
    set proxy roles -- thus, it cannot do what untrusted
    code with appropriate proxy roles can.

Re: External Methods, Proxy Roles, and Executable Security


max 4000 letters.
Your nickname that display:
In order to stop the spam: 3 + 2 =
QUESTION ON "DSM"

EMSDN.COM