Security in Plone Sites

6 min read

Download code from here

More about securityFor a closer look at a variety of Plone-related security information, visit Erik Rose and Steve McMahon’s excellent Plone Conference 2008 talk, visit

Restricting TCP/IP access to localhost or LAN host

One of the simplest things we can do to secure our system is to operate our Zope 2 instances only on the IP addresses that they are required to listen on.

In most cases, it is (or localhost, as it is commonly referred to) but it can also be a LAN host that is a private, non-routable IP address used only on your local area network (LAN).

In this article, we will not cover LAN hosts. However, we suggest you consider using them when you need to access instances from another host on the LAN; otherwise, just use localhost.

In the case of LAN hosts, once confgured, they will protect ports from being accessed by the outside world (that is Internet). However, it will allow them to be accessible from the LAN where you may want to confgure monitoring, for example via Munin , Zenoss (, and so on.

What we will cover is how to use the localhost IP address.

In 07-security-localhost.cfg, we have:

[buildout]extends = 06-deployment-optimization-munin.cfg

[instance1]http-address =

[instance2]http-address =

You will notice we have re-configured the http-address parameter to include the entire HTTP address and not just the port number.

You will also notice we have used the private, non-routable localhost address

Now run Buildout:

$ bin/buildout -c 07-security-localhost.cfg

Afterward, in parts/instance1/etc/zope.conf, you should see:

# valid keys are "address" and "force-connection-close"
# force-connection-close on
# You can also use the WSGI interface between ZServer and
# use-wsgi on


This means that our instances will listen for connections only on; any attempt to connect from another host will fail.

More about localhostFor more information about how the localhost really works, visit For our purpose though, we can think of running the Plone site on localhost as “having a party that only your laptop or development workstation can join”.

Managing IP addresses and ports effectively

As your production configuration grows, it may become more diffcult to manage a large number of IP addresses and ports.

As such, it is often helpful to have them defned in their own part.

In 07-security-ports.cfg, we have:

[buildout]extends = 07-security-localhost.cfg

[hosts]localhost =

[ports]instance1 = 8081
instance2 = 8082

Notice that we are not using these definitions for anything yet. But we can use them like this:


Effectively from now on, we have to change IP addresses and port numbers only in one place (assuming we change all static references such as to the new syntax).

Configuring the Zope 2 effective user dynamically

Another simple thing we can do to secure our system is to operate our Zope 2 instances with only those operating system users who have enough permission to execute the instances. In fact, Zope 2 will not run as root on UNIX-like systems.

However, we frequently forget to do this. More importantly, sometimes we want to be more explicit with our configuration. This is where the effective-user parameter comes in handy. If no effective user is set, then Zope 2 will run as whoever executes the process.

You could set the effective-user manually or you could use the gocept.recipe.env recipe ( to set it. In the case of manual configuration, you may find it tedious to test your production configuration on systems that do not have the desired effective user (or you may not; this is mostly subjective). In the case of no configuration, you may find it annoying to be reminded that you cannot run Zope 2 as root when you get to production (or you may not; this is also subjective).

In any event, we can formalize the configuration and automate the username selection process as follows.

In 07-security-effective-user.cfg, we have:

[buildout]extends = 07-security-ports.cfg
parts += env

[env]recipe = gocept.recipe.env

[instance1]effective-user = ${env:USER}
[instance2]effective-user = ${env:USER}

Now run Buildout.

$ bin/buildout -c 07-security-effective-user.cfg

Afterward, in parts/instance1/etc/zope.conf you should see:

effective-user aclark


This technique has several subtle, but important advantages over manual, or no configuration:

  • The effective user is always set, so even if you try to start Zope 2 as root, it will run as the effective user
  • The effective user is set to the user that runs the buildout, which means you can change the effective user easily
  • The ${env:USER} variable can be used to configure user settings for additional services such as Pound, Varnish, and so on.

Installing Cassandra to audit through the web (TTW) security

If you ask anyone familiar with Plone about the permissions settings in the Security part of the Zope Management Interface, you are likely to get the following response:


That is because with so many possible permutations of settings, it is almost impossible to manage them all effectively by pointing and clicking.

The next thing out of their mouth is likely to be:


That is because Plone’s workfow feature provides a much better way to effectively manage large amounts of permission changes.

However, people do not always use workfow. They point and click away anyway, despite the warnings. You, however, have been warned. It is much better to manage permissions with workfow as compared to pointing and clicking on Permissions in the ZMI.

Permissions and roles in the ZMI

If you do not believe me, consider this.

If you browse to http://localhost:8080/Plone and click on Site Setup | Zope Management Interface | Security, you will see almost two hundred permissions that look like the following (first ten):

Security in Plone Sites

Next to each group of 10 permissions are checkboxes that correspond to the possiblerole assignments:

Security in Plone Sites

Hopefully, enough has been said. The point again is two-fold:

  • The ZMI opens the gateway to enormous complexity (categorically, not just with roles and permissions)
  • In the case of roles and permissions, managing this complexity is best left to workfow (in which case, role-to-permission mappings are configured by the state)

Roles and groups

Similarly, the same Plone folks will often remind you to assign roles to groups and not users, and put users in groups to enable them to perform various tasks.

They might say:


This may be followed by:


Why? This is because to manage intricacies such as which user can perform which tasks and where, you are better off using the right tool for the job, that is adding users to groups with proper role assignments.

Unfortunately, end users are still able to assign roles to individual users if they really want to via the Sharing tab or Local roles form in the ZMI. So, it is the site manager’s responsibility to make sure they do not, to avoid having a site littered with individual role assignments.

Subscribe to the weekly Packt Hub newsletter

* indicates required


Please enter your comment!
Please enter your name here