History for ZopeSecurityPolicies
??changed:
-
Security policies
**Note** -- This page has been replaced by
InterfacesWiki:SecurityPolicies!
Problem
Currently, security policies are embedded in software.
For example, !DTMLMethods (and their subclasses) enforce a
certain policy with code distributed accross:
- !DocumentTemplate
- !DTMLMethod call logic
- a !DTMLMethod validate method.
A change in a the policy involves changes in all three places.
This gets even worse as there are refinements of !DTMLMethods that
have different versions of the code that also implements the
policies.
Another example is a method that needs to check for permissions
that aren't necessary to run the method. For example, a method for
adding a folder may provide an option to add a user database to a
newly created folder. The "Add Folders" permission is needed to
add the folder, but the "Add User Folders" permission is needed to
add a user folder. The method that adds a folder has to check
whether adding a user database is allowed. It has code that
implements the current security policy, but that may be wrong for
future policies. In addition, it gets security context
information in ways that are subject to being faked.
Policy objects?
One possibility might be to define abstract security policy
objects that abstract policy decisions.
What are policy objects used for?
They are generally used to determine whether access should be
granted to an object.
They may also be used to ask if a class of access, defined by a
permission, is available in a context.
What constitutes a context?
The context may include:
- The AUTHENTICATED_USER
- The call history (e.g. the owner of the current method)
- Where an accessed value came from
- Whether an accessed value was acquired
The [Zope-2.1.6-Policy] provides an example.
How do we need to vary policies?
- Do different kinds of executables need different policies?
- Does a site need a single policy?
How are policies and security contexts managed?
Possible new security API
The primary goal of this API is to make it much easier for
applications to function securely by providing high-level
facilities for application code to make security checks. By making
implementation checks easier, we reduce the opportunity for error
and resulting security holes. Also, management of contextual
information is automated, reducing both the chance of errors and
avenues for subverting the environment (by replacing
AUTHENTICATED_USER for example).
Application context is managed on a per-thread basis. An access
method is used to obtain a security manager and methods on the
security manager are called to perform security checks::
import !AccessControl
security=!AccessControl.getSecurityManager()
# A piece of code that wants to validate access can call validate:
security.validate(access, container, name, value)
security.validate(name='foo', value='o')
# We can also just check permission
security.checkPermission('Manage properties', foo)
An ExecutableObject may have information, such as proxy roles,
or owner information that is used by the security policy. For this
reason, executables must push themselves onto the security context
stack::
# an executable pushes itself onto the security
# context.
security.addContext(self)
try:
# do stuff
finally:
# pop. We pass ourselves as a check. If we're not on
# the top of the stack, someone we called screwed up!
security.removeContext(self)
Executable code must be written carefully, using a try/finally, to
make sure that executables get removed from the security context when
they complete their work.
Finally, there may be a need to be able to provide different
security policies for different sites or for different kinds of
executables. To change the policy for a site, we might have::
import !AccessControl
p=myPolicy(...)
!AccessControl.setSecurityPolicy(p)
to change the policy for an excutable, we might have::
# an executable pushes itself onto the security
# context.
security.addContext(self, self.policy)
try:
# do stuff
finally:
# pop. We pass ourselves as a check. If we're not on
# the top of the stack, someone we called screwed up!
security.removeContext(self, self.policy)
Note how carefuly we do this. :)
Policies added by executables only apply within the executable's
context and not within sub-contexts created by called executables.
Here are the relevent interfaces:
SecurityManagement -- Provides methods to get a security manager or
change the default policy
SecurityPolicy -- For implementing a policy
SecurityManager -- For checking access and managing executable
context and policies.