Plone.protect - no writes on GET is a broken assumption

Hi there,

one core principle of plone.protect is that no ZODB writes should happen during a GET operation other a transaction will be doomed and the Plone user will see the annoying "Confirm..." action which appears to most users as an error or whatever - at least not expected behavior.

This core assumption if broken in my opinion.

GET defines a contract between the browser and server. It does not define how the underlaying system should behave. Write actions may happen for example for performing additional logging or whatever. It is not up to the framework to decide what a good and what a bad request is and how it is supposed to work.

In a current project our customer uses Products.AutoUserMakerPASPlugin which some OAuth-ish authentication process where an incoming request from an external authentication source triggers writes while the requests passes PAS and this particular plugin. In particular Products.AutoUserMakerPASPlugin updates member properties as part of the GET requests triggered by a redirection of the external authentication source. So the users logins and gets confronted with the "Confirm action" form of Plone/plone.protect. The only option is to disable plone.protect completely for the site (in this case customer does not want to fork and maintain a customized version of Products.AutoUserMakerPASPlugin).

As said: this core principle of plone.protect is broken from ground up. Anyway...we are currently thinking about adding some support of "trusted referrers" where we would defined a list of URLs that would be considered as trusted in order to by-pass plone.protect. Not a safe solution but better than hacking other add-ons as well that would also trigger writes upon GET. Referrers can be faked, not a safe solution...anyone with a better idea?

-aj

I think you've got that core principle wrong: plone.protect doesn't care what the request method is; it cares whether the db is being written in a request that does not have an authenticator token. The request from your external auth provider would also be blocked if it was a POST request without a token.

This looks to me like a bug in Products.AutoUserMakerPASPlugin and I think the best solution is to make it disable CSRF checks for the request (or whitelist the particular objects that it modifies). Products.AutoUserMakerPASPlugin is in the collective so no need to fork.

2 Likes