Hardening Plone
Purpose
Do you need to run a highly secure Plone site? This document will tell you how to do it. Obviously no two Plone implementations are equal, but this document will give general guidelines on hardening your Plone site. The targeted audience is not the average system administrator, although the document may contain useful general tips. The document describes how to achieve a high-security Plone setup that would stand up under serious scrutiny. The methods described here have been deployed in a site that has been audited by a professional security company, and in a later stage by a world renowned accounting firm. The Plone site in question has been certified for use in an extremely sensitive environment.
The good news is that Plone is pretty secure as-is, but with a few extra precautions, you can have a seriously secured environment.
Prerequisities
You'll need some skills to be able to secure your Plone instance, and in some cases you'll need root access to your machine. Also, some security precautions may interfere with the way your site is accessible, and may not be acceptable for your specific site. To repeat: security is of the focus here, not usability.
For this document we assume you will use Apache 2.x as a front end for your site. This will significantly increase your configuration options. In case you do not want to do that, you'll need to find out how to configure the settings below for your specific setup. However, we really recommend to use a webserver as a front-end anyway, not Zope directly.
The document will touch a few different areas, all of which may hold potential security issues. In all examples, we use the domain secureplone.org as a fictional secure site.
Modifications outside of Plone
Use HTTPS instead of HTTP
One obvious security precaution to take is to enable HTTPS for your site, and you may even decide this is the only way user may access the site. This will ensure that all information over HTTP is encrypted. As a reminder: if you allow both, information that is sent over HTTP may still be sent unencrypted whenever a user decides to switch to HTTP, so this could be a consideration to allow HTTPS only.
Switching to a HTTPS setup is not straightforward, you'll need to understand how to obtain and install a certificate on your web server, and how to configure the server.
You'll need the following:
- a certificate for your domain, preferably one that is signed by a recognized authority like VeriSign, Comodo, Thawte, etc.; if you create your own certificate, the browser will warn end users that the certificate is self-signed which is not a problem per se, but may not give the end user the confidence that is needed;
- a server configuration that enables HTTPS and, if you like, disables HTTP.
Getting a certificate is beyond the scope of this document, but basically you can order a certificate anywhere for a given domain, and install it on your favorite webserver. Most professional vendors will provide you with a detailed setup for your server.
Relevant configuration for Apache 2.x is as follows:
<VirtualHost www.secureplone.org:443>
ServerName www.secureplone.org
# Turn on the engines!
#
SSLEngine on
SSLProtocol all
# SSL certificates
#
SSLCertificateFile /etc/apache2/ssl/secureplone.org.crt
SSLCertificateKeyFile /etc/apache2/ssl/secureplone.org.key
SSLCertificateChainFile /etc/apache2/ssl/secureplone.org.ca-bundle
...
</VirtualHost>
assuming your certificate is secureplone.org.crt, key is secureplone.org.key and the chain of trust is available in secureplone.org.ca-bundle. The key file is generated by yourself when taking the necessary steps to order a certificate, the certificate and the bundle will usually be part of the product you'll receive when ordering a certificate. If you decide to generate a key using a passphrase, remember that starting Apache will ask for this passphrase when starting, thereby effectively disabling automated start/restart. Use the SSLPassPhraseDialog option to re-enable.
You may want to decide to only allow the most secure version of SSL that is suported by all popular browsers, SSL v.3. To do that, change the line 'SSLProtocol all' into 'SSLProtocol SSLv3'.
Cookies anyone?
Cookies are small pieces of information that are generated by a service on the web and stored on the client machine. This is the only way to maintain persistent data on a client machine, and is often used to store session information. In the case of Plone, cookies are used to store session information in case the user logs in using the login form; the cookie holds the session id for the logged in user. Would this session id be hijacked, someone could abuse your session. Using HTTPS prevents cookie detection on the network, but cookie hijacking may still be possible using cross-site scripting.
Cookies are not inherently unsafe, but suffer from a few drawbacks from a security point of view, when used without precautions: cookies
- are stored on the client machine, and are readable by anyone with access to that machine;
- are readable by JavaScript;
- are sent over the web in plain text, in the HTTP headers
Cookies as they are used in Plone also suffer from these problems. Given the prerequisite of using Plone over HTTPS, the following extra settings can be used for the cookie: 'HttpOnly' and 'Secure'. The easiest method to do this with the least impact is using the Apache mod_headers module, with the 'edit' action (available from Apache 2.2.4):
Header edit Set-Cookie ^(.*)$ $1;Secure;HttpOnly
Older versions of Apache can't do this, neither can nginx. In these cases, you may want to take a look at dm.zopepatches.cookies, which patches Zope's publication mechanism. (See also this bug report on Launchpad.) Also note that the suggested patch has been included in Zope 2.12.0 b1, so Plone 4, which will use Zope 2.12 or higher, won't have this problem.
HttpOnly makes sure that the cookie can only be set or read by HTTP requests, not from within JavaScript or other client side scripting. The 'Secure' setting ensures the cookie may only be sent over HTTPS. This of course only applies if you are actually using HTTPS.
Using basic authentication
Another method of hardening your Plone instance is to not use cookie authentication, but instead use basic authentication. Whether you can actually do this may depend on your customer demands, since this authentication method will use a pop-up to ask for user authentication; this may be unacceptable. If you want to use this method, simply log into your ZMI, go to the acl_users tool within your Plone instance, choose plugins and then 'Challenge plugins' and place credentials_basic_auth above credentials_cookie_auth. You may also want to customize your login_form and portlet so as to force users to use the basic authentication. Note however, that basic authentication is... well, basic. When using HTTPS however, it is pretty secure.
Using client side certificates
Probably the most secure way of authentication is using client side certificates over SSL to do client authentication. This however calls for some organization in creating and distributing the client side certificates, and would require a use case where end users log in always using the same client machine; client side certificates are installed within the client, usually a browser. Also, you'll need a PAS plugin to do client certificate authentication.
Disallow client side caching
Would you like to disallow client side caching for whatever reason, for example to make sure that no information remains on the client machine after the session ends (N.B. it is courtesy of the client implementation to respect the cache settings!), you may want to rewrite the HTTP headers that indicate caching, 'Pragma' and 'Http-Cache'. The least-impact way of doing so is using the mod_headers module of Apache, and adding the following configuration.
Header set Cache-control "no-cache, no-store" Header set Pragma no-cache
A somewhat unexpected side effect of this configuration is that IE7 interprets the 'no-cache' setting in Cache-Control to forbid document downloads to the client machine. If this is a problem, use the header:
Header set Expires 'Sun, 17 Dec 1989 07:30:00 GMT'
instead.
Modifications in Plone
Using LoginLockout
A very basic way of securing your site is to limit the amount of times a user can enter an incorrect password. This protects a site from a brute force attack, where someone just tries thousands of passwords to login.
There is a product called LoginLockout which disables a user account after a configurable number of incorrect attempts. For more information, see http://plone.org/products/loginlockout. To use it, add this to your buildout:
[instance]
eggs +=
Products.LoginLockout
Hiding all templates from Anonymous users
By default, most of Plone's templates are viewable by non-logged-in users (Anonymous). As we know, this will display no valuable information, as Zope's permissions system takes care of that.
However, to some people (including those who do security audits) it just feels safer if an "Unauthorized" is displayed. The product iw.rejectanonymous does just that. For all templates except some (like login_form), it will redirect Anonymous users to the login form. This comes with a performance penalty of about a factor 3, but security is the issue here, not performance, right?
Hiding selected templates from Anonymous users
If your site has some pages that Anonymous should be able to see, hiding all templates is not feasible.
At least make sure that you hide the member_search_results template if you run a Plone version before 3.3.4. (See Plone ticket #9923)
Setting up quota
Some auditors see an absence of size limits on uploaded files as a security issue. If this is the case, you may want to take a look at the Quota product. It adds a content type for a folder of limited (configurable) size. Also, there are ways to limit Plone's upload size for individual files.
System environment
Apart from setting up Plone and the web service, it is very important to set up the system that Plone runs on properly. This article is not intended to delve in depth into system security, but a few hints may help.
Our company uses Debian Gnu/Linux for all servers. This Linux distribution is quite secure out of the box. Whatever distro you want to use, make sure the following procedures are in place:
- apply security patches, either automatically or by hand;
- run your Zope/Apache within a jail, that means within a 'chrooted' environment;
- use a firewall, for example iptables, to allow only connections that are really necessary;
- allow access to the server command line only using ssh;
- consider using DenyHosts to prevent unlimited login attempts via ssh;
- alternatively, make ssh accessible only through a VPN;
- limit disk quota for Zope user, so the filesystem cannot be filled up completely;
- prevent other users from reading Zope's Data.fs (and .cfg files if these contain passwords).
Further information
https://www.certifiedsecure.eu/

Author: