-
-
Notifications
You must be signed in to change notification settings - Fork 83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: disable CSRF protection on @history endpoint #1877
Conversation
@nileshgulia1 thanks for creating this Pull Request and helping to improve Plone! TL;DR: Finish pushing changes, pass all other checks, then paste a comment:
To ensure that these changes do not break other parts of Plone, the Plone test suite matrix needs to pass, but it takes 30-60 min. Other CI checks are usually much faster and the Plone Jenkins resources are limited, so when done pushing changes and all other checks pass either start all Jenkins PR jobs yourself, or simply add the comment above in this PR to start all the jobs automatically. Happy hacking! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to understand the context better here. This error only happens if a GET request is trying to write changes to the ZODB. In theory that should not happen if we're just reading the history. So let's check and make sure this doesn't indicate a problem we need to fix. Someone needs to debug in https://github.com/plone/plone.protect/blob/master/plone/protect/auto.py#L283 and check what objects are in registered
@davisagli Thanks for information. I looked into this and found that plone.protect checks if the parent of current context (which is the obj stored in registered )implements the IPortletAssignment interface here https://github.com/plone/plone.protect/blob/213f1c4da8cc7ce330edcc813868bbcdc2d1eecb/plone/protect/auto.py#L259 I tried implementing in the get See in ef11130 I would like to have your thoughts on this. Please also see https://github.com/plone/plone.protect/blob/213f1c4da8cc7ce330edcc813868bbcdc2d1eecb/plone/protect/auto.py#L246-L250 |
This is a casual comment: I did not fully grasped your issue 🤣 |
@ale-rt Ignore that line please :) |
I will ignore it when it's gone 🙈 |
Sorry, this is completely wrong and I don't think you've understood what plone.protect is trying to do yet. The parent of a content item is never a portlet assignment. Let me try to explain what plone.protect is doing a bit more. In general, plone.protect tries to stop any changes from being written to the database if the user is logged out and making a GET request, because that is rarely intended and could be a CSRF attack (where an attacker tricked the user into visiting a page which loads the GET request from Plone). There are some exceptions where this is allowed:
My point about this PR is that we haven't yet identified what object is being written in this request. Until we do that, we can't evaluate whether it is safe. So let's please focus on identifying the object instead of bypassing the protections. My guess is that is some structure that gets created by CMFEditions which is created implicitly if the object doesn't have a history yet. But assuming I'm correct, that should be fixed by either updating CMFEditions to not write the new empty history, or updating plone.protect to consider that object safe, and then we don't need to disable anything here. Edited to add: Ah, I see you said the object which was modified is the parent of the current context. Hmm. Then we need to see if we can find why that is happening. That doesn't sound like something I would expect from reading the history. |
@davisagli My issue is exactly what you mentioned in last two lines above in your comment. Although plone.protect applies CSRF checks to all requests by default, I'm also aware about the exception cases above and also mentioned along these lines https://github.com/plone/plone.protect/blob/213f1c4da8cc7ce330edcc813868bbcdc2d1eecb/plone/protect/auto.py#L260-L271 Certainly this issue only occurs when requesting a specific version of a current obj. such as
I will take a step back and debug it this weekend let's see what I can find. Thank you anyway for the explanation! |
@davisagli This is happening when we are managing the parent "current state" using Even if we are restoring the original state above, the plone.protect is marking it as "registered" for writing to db. https://github.com/plone/plone.protect/blob/213f1c4da8cc7ce330edcc813868bbcdc2d1eecb/plone/protect/auto.py#L220 Should we have a transaction savepoint that we can rollback like we did a level before when calling that wrap in Product.CMFEditions itself? |
@nileshgulia1 Good debugging. The problem seems to be that I think we should try updating https://github.com/plone/Products.CMFEditions/blob/c9ff225ffb7edefccc98b0c4b3db6a8b2dd0eeb0/Products/CMFEditions/CopyModifyMergeRepositoryTool.py#L518 to move it one line earlier, before the rollback, and see if that helps. I did a quick test locally and that seems to help. Let's make a PR for CMFEditions and see if all tests pass. |
Fixed the root cause in plone/Products.CMFEditions#120 instead. |
When accessing endpoint on a successful GET call to
@history
I get below error/warning.📚 Documentation preview 📚: https://plonerestapi--1877.org.readthedocs.build/