[SOLVED] plone.protect @@confirm-action triggered by GET on /view methods in Plone 6.0.0a6

I have the weird situation that my Plone 6.0.0a6 installation (build from scratch as part of a migration project generates @@confirm-action redirect (from plone.protect). This happens with GET requests on the default view of content objects. Pasting an URL like http://localhost:42080/eteaching/technik/produkte/phpnukesteckbrief/view into the browser address bar regenerates the redirect in a reproducible way over and over again. A restart and reload usually solves the problem.

Broader context: I came across the error with my zopyx.typesense search engine plugin which generated the result page of a search using JS on the fly. The links to related Plone objects all end view /view...so their default view. Clicking on such a link (in some cases) causes the plone.protect redirection and then when copy & paste the related URL manually...and there is nothing in the implementation that would modify the related content-object during a GET request.

Might be image scaling?

I think you can print/log/dump (the oids of) the changed objects right here: plone.protect/auto.py at f2016f5d3b9d0ee071fa442cc5e818da760bb4fc · plone/plone.protect · GitHub .

Might be a nice change if we'd logger.debug the oids before transaction.abort().


A request for http://localhost:42080/eteaching/materialien/literatur/schmidt-j-wilbers-m-2006/view has this list for registered. And the request is considered as safe = False for the content object itself.

[<Literature at schmidt-j-wilbers-m-2006>, <BTrees.OOBTree.OOBTree object at 0x10f839040 oid 0x254c403 in <Connection at 108df20d0>>]

I wonder what is in the OOBTree.

I can not recall exactly was. It is irrelevant because the loop over the registered object list already marks the first entry as unsafe.

I also get the same issue but only with the context object like

[<TestReport at acrobatsteckbrief>]

when clicking on object link from the folder contents view.
This is smelly and odd...and happening since 6.0.0a6

I think, this is right direction based on my observation:

  • content objects of one particular type without images do not cause the error
  • content object with images cause the error. Clicking on confirm resolves the issue for this particular content object and the view renders from this time on correctly

Since the content is migrated/imported using collective.exportimport, there might be another step necessary for recreating the image scales programatically? Any idea @pbauer ?

From the Plone 6.0.0a6 release notes:

plone.namedfile :

  • Creating a tag no longer generates the actual scale. The scale is only created when a browser really requests it.

Shouldn't touch the context though, unless it is the first time an annotation is set.
That's why I figured that the content of the btree might be useful data - if there's only the image stuff that might be it.

Good luck and have fun!

In the context of having only the current context object in the list, I also see this error:

> /Users/ajung/src/plone6.buildout/eggs/plone.protect-4.1.6-py3.9.egg/plone/protect/auto.py(244)_check()
-> try:
> /Users/ajung/src/plone6.buildout/eggs/plone.protect-4.1.6-py3.9.egg/plone/protect/auto.py(245)_check()
-> check(self.request, manager=self.key_manager)
zExceptions.Forbidden: Form authenticator is invalid.

Another observation: when I edit an object through the Plone UI before actually viewing it, the problem disappears. I assume, I need to recreate all image scales manually as part of the content migration import.

@mauritsvanrees do you have any idea how trigger the automatic regeneration of all scales for all objects with image fields programmatically?

Fun fact: plone.protect also requires a confirmation for /manage_main in our case...#wtf

Likely related, if scales are indeed the cause:

It can be that something is still missing there, that more such write-on-read allowing is needed for scales.
(I don't see a proof above that this is the actual problem, but it could be.)

  • Get all objects (via catalog or ZopeFindAndApply)
  • For each object iterate over all fields.
  • For each field that is a NamedBlobImage, use code similar to what is in plone.namedfile.adapters to iterate over all available scales and generate them. But be sure to set pre=False in this line. That will trigger really generating that scale again with Pillow.

BTW, I do get a bit more csrf protection messages in Plone 6 than in Plone 5, but I have not tried to dive into what would cause that.

I think that the issue is resolved (for now). The original migration import happened against Plone 6.0.0a4 with the upgrade to a6 using the Plone migration steps. Then the problem appeared.

A fresh import into a new a6 site does not show the issue :man_shrugging:

For me: problem resolved so far...but I don't know if there is anything to be done or fixed on the Plone migration side?!