Skip to content
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

Improved/corrected documentation for the DOS protection options #1180

Merged
merged 5 commits into from
Nov 2, 2023

Conversation

d-maurer
Copy link
Contributor

@d-maurer d-maurer commented Oct 31, 2023

#1177 has shown that Zope's DOS protection options documentation is partially wrong and difficult to understand.

This PR significantly extends the documentation by a description of the process influenced by the options and a precise specification of their imposed limits.

@mauritsvanrees #1177 might indicate that Plone needs a higher form-memory-limit default (currently 1MB). What is your experience?

@d-maurer
Copy link
Contributor Author

The failing "Windows py3.7" test is:

Failure in test test_scored_search (Products.ZCatalog.tests.test_catalog.TestScoring)
...
  File "d:\a\zope\zope\.tox\py37\eggs\products.zcatalog-7.0-py3.7.egg\products\ZCatalog\tests\test_catalog.py", line 1120, in test_scored_search
    self.assertEqual(brains[0].title, '111')
...
AssertionError: '11' != '111'

We know that some ZCatalog tests are not robust wrt. load conditions and therefore can occasionally fail. But, I have not yet known that the above test belongs to them. I will restart the tests and see what happens.

Copy link
Member

@mauritsvanrees mauritsvanrees left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The updated documentation LGTM, thanks.

Dieter Maurer wrote:

@mauritsvanrees #1177 might indicate that Plone needs a higher form-memory-limit default (currently 1MB). What is your experience?

In my experience, only sites with plone.restapi installed (this includes all sites using the default Volto frontend) are affected. In such a site, if you try to upload a file or image larger than 1MB, you get an error:

zExceptions.BadRequest: data exceeds memory limit

See also plone/Products.CMFPlone#3848.

On a few sites I have increased the form-memory-limit to 10MB, which at least seems fair for images. I wondered about doing a patch in Products.CMFPlone to update this limit, but then we would have to be careful to not override a manual setting in zope.conf. I would be happy with a higher limit in Zope.

In a pure Plone ClassicUI site without plone.restapi installed, with the default settings I can upload a 22MB file without problem. There the uploaded file is read in a way that does not trigger the limits.

With plone.restapi the error already happens when calling extractCredentials on the PAS plugin that comes with the package. The json_body function that is used there should probably be changed along the lines of your suggestions in #1177 (comment). This function is used all over the place though, so this could have unwanted side effects.

I think I will create a PR for plone.restapi that catches the BadRequest error in the PAS plugin. That fixes the basic error for ClassicUI at least.

@d-maurer d-maurer changed the title Improved/corrected documentation for the DOS protection options Improved/corrected documentation for the DOS protection options; increase form-memory-limit default Oct 31, 2023
@d-maurer
Copy link
Contributor Author

In my experience, only sites with plone.restapi installed (this includes all sites using the default Volto frontend) are affected. In such a site, if you try to upload a file or image larger than 1MB, you get an error:

zExceptions.BadRequest: data exceeds memory limit

@mauritsvanrees
If Plone (or plone.restapi) reads whole file contents into memory, it does something wrong. We would not want to have the content of a large (e.g. 1 GB) file in memory - it would be there not once but several times (e.g. once as part of the complete body and once as value in the JSON object).
Files (and to a smaller extend images) should be transferred via multipart/form-data requests. They represent files via file like objects which can be efficiently (i.e. without high memory requirement) transformed into blobs.

I suggest to rework the plone.restapi API. API requests should consist of a JSON object and optional attachments. The JSON object is for small information, the attachments carry potentially large information. Without attachments, the JSON object could be transferred in an application/json request (which would ensure backward compatibility); requests with attachments would use mutipart/form-data requests. This would ensure that attachments are represented as file like objects and not be read as a whole into memory.

mauritsvanrees added a commit to plone/plone.restapi that referenced this pull request Oct 31, 2023
The result was never used, and it may fail when the request is too large to read.
This is a problem since at least Zope 5.8.4, introduced in Plone 6.0.7.
See plone/Products.CMFPlone#3848 and zopefoundation/Zope#1180.

This PR is an alternative to #1726.  See discussion there.
@mauritsvanrees
Copy link
Member

Based on the feedback from @mauritsvanrees, the PR now also increases the default for form-memory-limit from 1 MB to 8 MB. Hopefully, this will avoid the need for Plone to configure this option.

Thanks!

@mauritsvanrees
Copy link
Member

I am happy with this. @d-maurer Can you merge?

@dataflake @icemac A Zope release with this would be good. Would that be possible today or tomorrow? I am trying to release Plone 6.0.8 and want to have the increased limit in there, either with a new Zope version or with a temporary patch in CMFPlone.

@dataflake
Copy link
Member

@mauritsvanrees I don't mind doing releases but I would really appreciate more warning than "today or tomorrow". I am sure releasing Plone 6.0.8 didn't occur to you just today, right?

@d-maurer
Copy link
Contributor Author

d-maurer commented Nov 2, 2023 via email

@mauritsvanrees
Copy link
Member

@dataflake Sorry for not communicating earlier.

The problem with the low memory limit was already known (to Plone people) since shortly after the Plone 6.0.7 release from 21 September. Since then some fixes were done to counter this (in plone.recipe.zope2instance and plone/cookiecutter-zope-instance), but they still required a configuration change. I had hoped that someone (most likely a Plone core developer) would have picked this up already, no matter if that would be by a change in Zope or in Plone. But that did not happen yet. So much for wishful thinking...

Meanwhile there actually is already a Plone 6.0.8 release candidate since last Thursday. I wanted to do the final release two days ago. But finally I decided we should not ship with this low default limit, so I postponed the release (also for one other, totally unrelated problem).

@d-maurer
Copy link
Contributor Author

d-maurer commented Nov 2, 2023 via email

@mauritsvanrees
Copy link
Member

plone.restapi definitely needs some changes along the lines you have indicated here and elsewhere.

As a quick fix, I think I will open a PR in plone.restapi to override FORM_MEMORY_LIMIT with a larger value (maybe 16MB) if it is at the current default of 1MB. Then only users of plone.restapi are affected, and the configuration options are still all there.

@d-maurer
Copy link
Contributor Author

d-maurer commented Nov 2, 2023

As a quick fix, I think I will open a PR in plone.restapi to override FORM_MEMORY_LIMIT with a larger value (maybe 16MB) if it is at the current default of 1MB. Then only users of plone.restapi are affected, and the configuration options are still all there.

Maybe, overriding ZPublisher.HTTPRequest.ZopeFieldStorage.VALUE_LIMIT is a better option. If plone.restapi sets it to None, then there is no longer a size limitation for request["BODY"] accesses.

@d-maurer
Copy link
Contributor Author

d-maurer commented Nov 2, 2023

I removed the default change for form_memory_limit again as @mauritsvanrees plans to resolve the Plone related problems elsewhere.

@d-maurer d-maurer changed the title Improved/corrected documentation for the DOS protection options; increase form-memory-limit default Improved/corrected documentation for the DOS protection options Nov 2, 2023
mauritsvanrees added a commit to plone/plone.restapi that referenced this pull request Nov 2, 2023
…es and images.

This seems a better way, then increasing the limit to 16MB.
See zopefoundation/Zope#1180 (comment)
@mauritsvanrees
Copy link
Member

Maybe, overriding ZPublisher.HTTPRequest.ZopeFieldStorage.VALUE_LIMIT is a better option. If plone.restapi sets it to None, then there is no longer a size limitation for request["BODY"] accesses.

Okay, let's go with that after all. Thanks.
See plone/plone.restapi#1729

@dataflake
Copy link
Member

@d-maurer OK, I suggest merging now

@mauritsvanrees Do you still need a Zope 5.8.7 release?

@d-maurer d-maurer merged commit f209925 into master Nov 2, 2023
22 checks passed
@d-maurer d-maurer deleted the dos_documentation branch November 2, 2023 13:59
@mauritsvanrees
Copy link
Member

@dataflake No need for a Zope release, the plone.restapi change will be enough for now. Thanks anyway.

FWIW, I tried the Zope master branch and its versions earlier this week, and all Plone tests passed.

tisto pushed a commit to plone/plone.restapi that referenced this pull request Nov 4, 2023
…1729)

* Allow uploads up to 16 MB.

This fixes a regression due to a low Zope form memory limit of 1MB used since Plone 6.0.7.
You can use ``dos_protection`` settings in ``etc/zope.conf`` to change the limit.
See plone/Products.CMFPlone#3848 and zopefoundation/Zope#1142.

* Changed patch: temporarily disable form memory limit checking for files and images.

This seems a better way, then increasing the limit to 16MB.
See zopefoundation/Zope#1180 (comment)
mister-roboto pushed a commit to plone/buildout.coredev that referenced this pull request Nov 4, 2023
Branch: refs/heads/main
Date: 2023-11-04T07:13:09+01:00
Author: Maurits van Rees (mauritsvanrees) <maurits@vanrees.org>
Commit: plone/plone.restapi@9f399ac

Temporarily disable form memory limit checking for files and images. (#1729)

* Allow uploads up to 16 MB.

This fixes a regression due to a low Zope form memory limit of 1MB used since Plone 6.0.7.
You can use ``dos_protection`` settings in ``etc/zope.conf`` to change the limit.
See plone/Products.CMFPlone#3848 and zopefoundation/Zope#1142.

* Changed patch: temporarily disable form memory limit checking for files and images.

This seems a better way, then increasing the limit to 16MB.
See zopefoundation/Zope#1180 (comment)

Files changed:
A news/3848.bugfix
A src/plone/restapi/patches.py
M src/plone/restapi/__init__.py
M src/plone/restapi/deserializer/__init__.py
mister-roboto pushed a commit to plone/buildout.coredev that referenced this pull request Nov 4, 2023
Branch: refs/heads/main
Date: 2023-11-04T07:13:09+01:00
Author: Maurits van Rees (mauritsvanrees) <maurits@vanrees.org>
Commit: plone/plone.restapi@9f399ac

Temporarily disable form memory limit checking for files and images. (#1729)

* Allow uploads up to 16 MB.

This fixes a regression due to a low Zope form memory limit of 1MB used since Plone 6.0.7.
You can use ``dos_protection`` settings in ``etc/zope.conf`` to change the limit.
See plone/Products.CMFPlone#3848 and zopefoundation/Zope#1142.

* Changed patch: temporarily disable form memory limit checking for files and images.

This seems a better way, then increasing the limit to 16MB.
See zopefoundation/Zope#1180 (comment)

Files changed:
A news/3848.bugfix
A src/plone/restapi/patches.py
M src/plone/restapi/__init__.py
M src/plone/restapi/deserializer/__init__.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants