Python Tales and Plone Stories


Debugging CSRF Protection False Positives in Plone

In light of the recent plone4.csrffixes security fix, I’d like to share some of our experiences in debugging and fixing CSRF protection false positives. Because plone.protects approach for automatic CSRF protection is pretty comprehensive (which is good), it can result in cases where there’s false positives – a dialog that is shown to the user asking them to confirm their intent (to prevent the request forgery), even though no actual CSRF attack has occurred.

Confirm action dialog

We’ve been using the automatic CSRF protection from plone.protect 3.x with Plone 4 for a little more than half a year now, before it was officially supported. We therefore hit quite a few situations where we had to debug false positives caused by a write-on-read, both the ones in stock Plone 4 (which now have been addressed), and ones caused in our own add-ons.

Particularly because of the recently introduced HTTP_REFERER check you should rarely ever hit those false positives any more, but if you do, here’s some techniques for debugging and fixing them.

How plone.protect’s auto CSRF protection works

CSRF protection (automatic or manual) in Plone is done via plone.protect. Plone 4 used to pin plone.protect == 2.x, which put a basic framework for manual CSRF protection in place. plone.protect >= 3.0, which was targeted at Plone 5, then introduced automatic CSRF protection.

OneGov Plone Theme

The package plonetheme.onegov contains a modern, generic, and responsive Plone theme we’ve been developing for the past 10 months. We are primarily using it for websites with additional OneGov modules installed. However, the theme is generic enough to work with standard Plone sites, too.

The OneGov theme is not just another Plone theme as it has some neat concepts. In this blog entry, I’d like to present the major technical features of this new theme.

Responsive Design for Mobile Devices

How to use responsive design for mobile devices?

By default, most webpages do not really work well on small displays (e.g. on smartphones). Usually, not all relevant information fits to the display – you are forced to scroll horizontally or zoom out which can become quite awkward. By using repsonsive design you can have your design dynamically adjust to the available screen width, giving you the best of your page, especially on mobile devices.

Setuptools Console_scripts Entrypoints and Buildout

If your Plone deployment story looks anything like ours, you probably have several Python packages that get pulled together by a project-specific buildout that lives in its own git repository.

While we try to keep those buildouts clean and pretty minimal, sometimes there’s need for little helper scripts that you want to execute from that buildout, but still should live in an appropriate package and therefore another repository.

Installing the Correct Plone Hotfixes

At 4teamwork we have dozens of different Plone sites running, old ones and new ones. Since we cannot migrate all the older sites to the latest version of Plone, we need to patch them, too. To further complicate the issue, for a site running e.g. Plone 3.0 more patches have to be applied than for a fresh install of Plone 4.3.

Git - Partially Applying a Patch

We are currently in the process of consolidating many of our packages for a large project into a single project.core package. We do this in order to simplify the dependency graph, testing, GitHub workflow and general maintenance. These are packages that we first decided should be optional, but now have grown to be such integral parts of the system that we have to have a hard dependency on them anyway.

ftw.tooltip Introduction - Add Tooltips to Your Plone Site

Plone has many great features, but sometimes it’s hard for a user to focus on the task at hand. Even more so if the user is not working with Plone all day.

To make the UI more expressive and to provide a better user experience, we built ftw.tooltip. It provides an easy way to add tooltips to your Plone site and works without customizing nor patching views, viewlets, forms, etc.

Construct Your Testing Data Using the Builder Pattern

Test data generation is always a hot topic when it comes to automated software testing. One of my first assignments at 4teamwork was to help with the testing. In the process I was browsing through the test suites of some big projects they are working on and noticed a lot of similar code related to data creation:

dossier = createContentInContainer(self.portal,

test_file = NamedBlobFile("lorem ipsum", filename=u"test.txt")
document = createContentInContainer(dossier,

This is very basic object creation code and I’m sure many Plone developers have written a fair amount of it. While this gets the job done, there is a lot of noise, that we don’t need to have in every test.