I've been looking into how we might add CSRF protection to z3c.form forms as
we will be including z3c.form in Plone 4.1. Currently in Plone, we use
plone.protect to add an authentication token to our forms and then check the
token in the methods that get called. (plone.protect is BSD licensed, but is
Zope2 specific.)

I think it's important for the integrator to be able to add an authentication
policy to all z3c.form forms on a site, so I'd rather not rely on having all
forms subclass some AuthenticatedForm.

I can see a number of possible ways to implement this

1. Add a hook into z3c.form.form.Form along the lines of::

    def update(self):
        super(Form, self).update()
        if self.refreshActions:

    def authenticateSubmission(self):
        if self.actions.executedActions:
            authenticator = zope.component.queryMultiAdapter(
                    (self, self.request, self.getContent()),
            if authenticator is not None:

This would allow integrators to register an ISubmissionAuthenticator that
would be called when there are actions to execute (so not when a form is just

2. Similar to (1) but fire an event. This would allow multiple submission
authenticators to be registered (e.g. for post-only as well as
check-authenticator), but this makes it more difficult to restrict
authenticators to only certain forms / requests / contexts.

3. Register a more specific version of z3c.form.button.ButtonActionsHandler
which performs the check before executing the handler. This has the advantage
of not requiring any changes to z3c.form, but the disadvantages that: only
button actions are protected, and would be executed per action handler execution
instead of once per submission.

I'd be interested to know how other z3c.form users approach CSRF protection
and what approach they would recommend.

Zope-Dev maillist  -  Zope-Dev@zope.org
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope )

Reply via email to