Zope is an application framework intended predominantly for web publishing. It has a reasonably well established user community, its Open Source, and it delivers on most the things its designed to without really challenging the status quo. Inside the project you'll find a few nice hacks, a lot of unfinished ideas, and a bureaucratic nightmare or two.
If you expect to get a lot out of Zope, expect to work for it. You will need to know Python, and you will want to consider maintaining your own fork of the code base (which is relatively easy if you know how to use version control software). You should also give heed to the oft quoted words of Antoine de Saint Exupery:
A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away.
I've made some progress towards simplifying Zope on Unix but its not at a particularly useful stage yet. With efficiency and security in mind, I've written software packages for Zope which more-or-less duplicate some features already found in the stock code. The packages are designed to be complementary, but could be used as replacements with little effort.
Zope has a fair number of outstanding security problems, these are my notes on the ones I know about, and how to cope with them. The dates represent the approximate time I became aware of the issue.
| promiscuous default privileges | Dec 03 2002 | |
|
No application can truly be considered World Class unless it boasts
promiscuous default privileges that administrators are forced to change, by
hand, after every new installation. Its a proud tradition in this industry, and
as good a reason to drink as any. The root of a freshly created object file
system in Zope is, usually, an OFS.Application object. Upon examining the
source to that class, (OFS/Application.py if you'd like to follow along) you'll
notice there are a bunch of objects contained within an instance which don't
show up via the Zope management interface but are accessible via acquisition
or direct traversal. A great example is the HelpSys object which, as you might
have guessed by the name, is a container for the online help system that ships
with Zope. By default, because of the promiscuous security settings of the root
OFS.Application object, anonymous clients are allowed to access HelpSys and
other "hidden" objects which can lead to information exposure vulnerabilities,
or worse. Workaround: Remove all permissions from the Anonymous role at the root-level object of your root-level ZODB. (To avoid breaking error handling, you will probably have to re-enable anonymous access for the root level standard_error_message object. This will hold true for any shared resource in the root container.) Once access to the root container is appropriately restricted you can create a new Folder (or Folders) to work out of but you'll need to adjust the permission settings for the Anonymous role in said folder(s) if you desire to publish content to anonymous clients. Again, what you achieve by nesting the base of your content one level deeper than the root container is the ability to stop anonymous users from traversing those "hidden" objects which live in the root container like HelpSys, and so forth. | ||
| misplaced trust in Host header | Feb 18 2003 | issue 1191 |
| Zope implicitly trusts the Host header in client requests. This leads to the potential for cache poisoning, log tampering, and [until recently] cross-site-scripting. (historically issue 813) | ||
| information leaks in OFS/Cache.py | May 14 2003 | issue 911 |
| Fix: Install my enhanced Caching API by replacing OFS/Cache.py with Cache.py, then apply patches cmassoc.diff and cachemanagers.diff. | ||
| misplaced trust in traversal stack | May 30 2003 | |
| I posted the details of this issue to the zope list when it occurred to me. The immediate implication is that the SiteAccess product needs a serious overhaul. There could be further ramifications, it needs to be researched more. | ||
| cross-site-scripting in error handling | Jun 23 2003 | issue 961 |
|
illegitimate promotion of text to markup in
SimpleItem.raise_standardErrorMessage() Workaround: Ensure the error_message variable undergoes contextual escaping in your standard_error_message. (This will break the display of some error messages, but its better than the alternative.) | ||
| cross-site-scripting enabled by ZPublisher | Aug 03 2003 | issue 1007 |
|
illegitimate promotion of text to markup in HTTPResponse.setBody() | ||
| trusted API unduly exposed | Aug 03 2003 | issue 1192 |
|
unprotected mutable objects are bad news
Workaround: Don't let untrusted users author RestrictedPython. (DTML objects, Script (Python) objects, etc.) | ||
| potential Denial of Service attacks via Script (Python) objects | ||
|
Multi-threaded Python programs are vulnerable to several DoS attacks if
they can't trust their threads to behave. This isn't really news, but its
brought up often enough that it deserves comment. In the past Zope made some
half-assed attempts to defang some of the more common attacks, but they hurt
more than they helped, so that code was [wisely] discarded. See also
issue 1284 and
issue 1329.
Workaround: Don't let untrusted users author RestrictedPython. (DTML objects, Script (Python) objects, etc.) Always run Zope beneath sensible resource limits to protect the host OS. | ||
| ZServer should never be run as the super-user. |
| When run as the super-user, ZServer supports the ability to bind to privileged ports then switch to an unprivileged uid/gid. Despite outward appearances, this feature is completely worthless. In light of the fact that ZServer is not a production-quality web server, nor was it designed to be one, the use of a gateway server is mandatory, and if anything need bind to a privileged port it would be the gateway server, not ZServer. It should be required that ZServer be run as an unprivileged user and bound to a unprivileged port, probably on the loopback interface of the same host housing the gateway server, but certainly firewalled off from anonymous access in any case. |