-------------------------------------------
What is it?
We use a white-list style security system in our views. It has two
main components.
- A security proxy is placed around objects that modify the database.
This proxy enforces security rules. The rules are based on our
custom
Launchpad security policy and on our permission settings. The
permission settings are set up in out .zcml files, and usually driven
by our interfaces. For instance, a bug will have methods that can be
accessed only if the current user for a request has a certain
permission for that bug's context (i.e., the project with which the
bug is associated). Also, utilities are usually registered with
security proxies on them, so they are obtained already
security-proxied.
- An import fascist controls what can be imported. You may only
import code in a module's __all__. This actually affects all code,
not just view code.
-------------------------------------------
Why do we do it?
Ultimately, the view code is responsible for security, as with many
other web applications and frameworks. There are ways for the view
to
bypass the entire security system, as discussed below.
However, the security system is intended to be a "belt and
suspenders"
for our view code, and we typically rely on it heavily. Bypassing
the
security system is (supposed to be) a very obvious gesture
(typically,
a use of "zope.security.proxy.removeSecurityProxy") that developers
and reviewers know is an unusual "break glass" action that calls for
extra care and scrutiny.
From a security profile perspective, our approach appears to have
been
fairly successful. The fact that our security is white-list means
that typically security errors are more of the sort "oops, person X
should have been able to do Y" than "oops, person X shouldn't be
able
to do Y!"
The approach certainly does have a complexity/comprehension cost for
the developers, but the fact that security can usually be configured
centrally, once, has arguably also been a win from a DRY perspective.
Being able to specify security for model classes in-line in the
Python
(via grok-based libraries) will hopefully be a nice improvement in
the
future, reducing or eliminating the need to go to an external, XML
file for these settings.
-------------------------------------------
What are the rules?
- Don't use removeSecurityProxy unless you really have to. Try to
see
if there is another way. When reviewing, make sure you are convinced
of the necessity. Using removeSecurityProxy is necessary sometimes,
and accepted, but a red flag.
- When writing something like a function that is imported directly by
views, or a helper method on a view, it should do one of the
following:
* return an object that is immutable (in Python, as opposed to C),
and that is not a collection, like None or a string or an int.
* return another view object (because it already has followed the
security rules itself)
* return a security-proxied object.
* return an immutable collection (i.e., tuple), or a newly created
non-database collection (i.e., a new list), of any of these things.
- To comply with our coding standards and the import fascist, always
import items within a module, not modules themselves. On the other
hand, if you truly must bypass the import fascist, import the module.
Because of this, importing a module should be regarded as a red flag
during the reviewing process, just like a use of removeSecurityProxy.
-------------------------------------------
That's it.
Thanks
Gary
_______________________________________________
Mailing list: https://launchpad.net/~launchpad-dev
Post to : launchpad-dev@xxxxxxxxxxxxxxxxxxx
Unsubscribe : https://launchpad.net/~launchpad-dev
More help : https://help.launchpad.net/ListHelp