- This page has been replaced by InterfacesWiki:SecurityPolicies!
Currently, security policies are embedded in software. For example, DTMLMethods (and their subclasses) enforce a certain policy with code distributed accross:
- 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.
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: