Add: [report] max_expand_occurrence option to separate from max_freebusy_occurrence

This commit is contained in:
Peter Bieringer
2026-08-01 18:52:08 +02:00
parent 6cdf0e75b4
commit 4a4e571cce
6 changed files with 27 additions and 4 deletions

View File

@@ -3,6 +3,7 @@
## 3.7.8.dev
* Fix: sharing/proppatch: reject in case of write-access but 'p' is in permissions
* Fix: sharing/by-map: catch collection path without trailing / (supporting "pimsync")
* Add: [report] max_expand_occurrence option to separate from max_freebusy_occurrence
## 3.7.7
* Fix: web plugin helpers httputils.serve_resource/serve_folder ignored their mimetypes and fallback_mimetype parameters and always used the built-in mapping, so custom web plugins could not serve additional file types with a correct Content-Type

View File

@@ -2191,6 +2191,19 @@ This is an automated message. Please do not reply.
#### [reporting]
##### max_expand_occurrence
_(>= 3.7.8)_
When returning an expanded report, a list of occurrences are
generated based on a given time frame. Large time frames could
generate a lot of occurrences based on the time frame supplied. This
setting limits the lookup to prevent potential denial of service
attacks on large time frames. If the limit is reached, an HTTP error
is thrown instead of returning the results.
Default: 10000
##### max_freebusy_occurrence
_(>= 3.2.3)_

4
config
View File

@@ -499,6 +499,10 @@ Content-Security-Policy = default-src 'self'; object-src 'none'
[reporting]
# When returning an expanded report, limit the number of returned
# occurences per event to prevent DoS attacks.
#max_expand_occurrence = 10000
# When returning a free-busy report, limit the number of returned
# occurences per event to prevent DoS attacks.
#max_freebusy_occurrence = 10000

View File

@@ -895,9 +895,9 @@ class ApplicationPartReport(ApplicationBase):
assert item.collection is not None
collection = item.collection
max_occurrence = self.configuration.get("reporting", "max_freebusy_occurrence")
if xml_content is not None and \
xml_content.tag == xmlutils.make_clark("C:free-busy-query"):
max_occurrence = self.configuration.get("reporting", "max_freebusy_occurrence")
try:
status, body = free_busy_report(
base_prefix, path, xml_content, collection, self._encoding,
@@ -909,6 +909,7 @@ class ApplicationPartReport(ApplicationBase):
headers = {"Content-Type": "text/calendar; charset=%s" % self._encoding}
return status, headers, str(body), xmlutils.pretty_xml(xml_content)
else:
max_occurrence = self.configuration.get("reporting", "max_expand_occurrence")
try:
status, xml_answer = xml_report(
base_prefix, path, xml_content, collection, self._encoding,

View File

@@ -813,9 +813,13 @@ This is an automated message. Please do not reply.""",
("headers", OrderedDict([
("_allow_extra", str)])),
("reporting", OrderedDict([
("max_expand_occurrence", {
"value": "10000",
"help": "number of expand occurrences per event when reporting",
"type": positive_int}),
("max_freebusy_occurrence", {
"value": "10000",
"help": "number of occurrences per event when reporting",
"help": "number of free-busy occurrences per event when reporting",
"type": positive_int})]))
])

View File

@@ -326,7 +326,7 @@ permissions: RrWw""")
def test_report_with_expand_property_max_occur(self) -> None:
"""Test report with expand property too many vevents"""
self.configure({"reporting": {"max_freebusy_occurrence": 100}})
self.configure({"reporting": {"max_expand_occurrence": 100}})
self._test_expand_max(
"event_daily_rrule_forever",
"20060103T000000Z",
@@ -336,7 +336,7 @@ permissions: RrWw""")
def test_report_with_max_occur(self) -> None:
"""Test report with too many vevents"""
self.configure({"reporting": {"max_freebusy_occurrence": 10}})
self.configure({"reporting": {"max_expand_occurrence": 10}})
uid = "event_multiple_too_many"
start = "20130901T000000Z"