Repository navigation
icalendar 7.1.3 security vulnerability patched #1464
stevepiercy
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
icalendar 7.1.3 security vulnerability patched
The icalendar team is pleased to announce that icalendar 7.1.3 has been released. This is a security patch release that fixes a vulnerability that was introduced in icalendar 7.1.0. It's recommended to upgrade icalendar versions 7.1.0 - 7.1.2 to 7.1.3.
Plone 6.2.0 is affected by this vulnerability. Plone 6.1.x is not affected because it uses icalendar 6.3.2, which is not affected.
Thanks to @tidusec on GitHub for the responsible report and the initial pull request, with additional guidance and help to improve regression testing by @mauritsvanrees from the @plone Security Team. Thanks to the @nlnet Foundation and its financial support from its NGI Zero Core grant program which helped create a responsive community around crucial free and open source software. This was the icalendar team's first security response, and it wouldn't have happened without this collaboration and support.
A CVE has been requested. A link to it will be published when it's available.
For the complete change log, visit:
https://icalendar.readthedocs.io/en/stable/reference/changelog.html
Summary
Component.__eq__compares subcomponents inO(2^n)time relative to nesting depth. Because the parser accepts arbitrarily nested components, a sub-kilobyte.icsfile is enough to make a single equality check run for minutes or hang indefinitely. Any application that compares parsed components (==,!=,in, set/dict membership, deduplication, test assertions) against attacker-supplied calendar data is exposed to denial of service.Details
Component subclasses
dictand stores children in a separate subcomponents list.__eq__(src/icalendar/cal/component.py:642-665) checks set-equivalence of children with two membership loops:Each
... not in ...test invokes__eq__on the children. For a nested chain, both loops descend the full subtree, so each level spawns two recursive comparisons:T(n) = 2·T(n-1)→O(2^n).Parsing does not gate this.
Component.from_icalbuilds the structure iteratively and imposes no depth limit, soBEGIN:VEVENTblocks can be nested to any depth (parsing the payload below is instant). The cost is paid only when a comparison occurs, and only when the operands are equal far enough down to keep both loops recursing, a condition the attacker controls by submitting equal subtrees.PoC
Measured on icalendar 7.1.x, CPython 3.14:
==timeA single uploaded file supplies both operands (two identical nested events), so no second input is needed. The same blowup occurs in round-trip checks (
cal == Calendar.from_ical(cal.to_ical())) and in any membership/dedup logic over subcomponents.Impact
Algorithmic-complexity denial of service (CWE-407). Unauthenticated; a few hundred bytes of input pin a CPU core indefinitely. It affects any service that parses untrusted iCalendar data and then compares components for equality or membership, including calendar sync/import endpoints, invite processing, dedup, and round-trip/normalization checks. It is not triggered by parsing alone, and a comparison against an early-differing object short-circuits harmlessly, so impact is limited to code paths that perform such comparisons.
Fix
Component.__eq__rewritten to walk an explicit stack instead of recursing, matching each pair of nested components exactly once. Equality is now linear in the number of components and preserves the existing multiset equivalence and commutativity semantics.Bug fixes
Component.__eq__is no longer exponential in the subcomponent nesting depth, removing a denial-of-service vector where a deeply nested component could take minutes to compare. See GHSA-cv84-9p8j-fj68 at GHSA-cv84-9p8j-fj68. @tidusecSupport icalendar
This release was made possible through a NGI Zero Core grant from the NLNet Foundation as part of a larger project to develop the Open Web Calendar stack.
https://nlnet.nl/project/OpenWebCalendar-recurring/
Funding development helps create a responsive community around the Python calendaring ecosystem.
https://pycal.org/
As free and open source software, icalendar thrives and grows only when it receives support from you. You can help icalendar keep up-to-date with your platform and continue to use it in your applications in many ways.
Join the icalendar community
The maintainer of icalendar, Nicco Kunzmann (GitHub: @niccokunzmann), gratefully appreciates the contributions for this release. See the list of contributors.
https://github.com/collective/icalendar/graphs/contributors
By fostering a warm and welcoming community around free and open source software, icalendar attracts both experienced and first-time contributors to participate. See how to contribute.
https://icalendar.readthedocs.io/en/stable/contribute/index.html
Additional references
Documentation
https://icalendar.readthedocs.io/en/stable/
Change log
https://icalendar.readthedocs.io/en/stable/reference/changelog.html
Upgrade guide
https://icalendar.readthedocs.io/en/stable/how-to/upgrade.html
PyPI
https://pypi.org/project/icalendar/
Issues
https://github.com/collective/icalendar/issues
Discussions
https://github.com/collective/icalendar/discussions
Mastodon
https://toot.wales/@niccokunzmann/
All reactions