SEC2-049: postulo-imap locks pyjwt 2.13.0, urllib3 2.7.0 and django 6.1.1, carrying 22 published advisories, and CI never audits the lock #24
Labels
No labels
bug
documentation
enhancement
performance
security
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Postulo/postulo-imap#24
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found on 2026-10-16 in a read-only security review of
postulo-imapat1375eb3, checked by a second, independent pass.Severity: Low · Category: Dependencies · Reference: CWE-1104 (Use of Unmaintained Third Party Components); OWASP A06:2021 (Vulnerable and Outdated Components)
Location:
uv.lock(pyjwt 2.13.0,urllib3 2.7.0,oauthlib 3.3.1,django 6.1.1,django-allauth 65.19.2)pyproject.toml:53(postulo @ git+...@925e3e9cd35a97617cc45b36ecdde862d04515b1).forgejo/workflows/ci.yml:47-48,55and.forgejo/workflows/release.yml:40,44(unversioned installer;uv sync --locked; no audit step)Issue
A pip-audit 2.10.1 run on 2026-10-16 against the exported lock reports
pyjwt 2.13.0with fourteen advisories (fixed in 2.14.0 / 2.15.0, including HMAC key-handling flaws that allow token forgery),urllib3 2.7.0with three (fixed in 2.8.0) andoauthlib 3.3.1with one (fixed in 4.0.0). The lock also holdsdjango 6.1.1, whose four security fixes in 6.1.2 pip-audit cannot see (postulo/postulo SEC2-044), anddjango-allauth 65.19.2. The core pin (925e3e9cd, five days and 210 commits behind the core's56fc9d531) is not the cause: the plugin's own lock has never been re-resolved, and the core's lock does not constrain it.The plugin's own dependency is
imapclient>=3.0(pyproject.toml:21), which talks IMAP over the standard library and the destination guard, so pyjwt and urllib3 are reached only through allauth's OpenID Connect in the test environment; in production the core's constraint file decides. No audit step exists in either workflow.Impact
The plugin's tests and every developer environment run with a JWT library that accepts forged tokens under some HMAC configurations and an HTTP stack with open advisories, and nothing in CI would say so. If the lock is ever shipped, the stale pins ship with it.
Fix
uv lock --upgrade(upgrading allauth brings oauthlib 4), re-pin the core to currentmainat the same time, and add the core'spip-auditstep and the checksummed installer toci.ymlandrelease.yml. Done when: pip-audit against the exported lock reports nothing and the CI workflow fails on a new advisory.Related
#14 (open) - the unversioned installer and the single Python tested; it does not mention the audit or the lock's advisories. postulo/postulo-apprise#13 (open) - names this repository's installer line and missing audit among the five others. #1 (closed) - "fix CI, pins" of 2026-09-15, about the CI not running at all. postulo/postulo-dav SEC2-048 - the same lock problem in the DAV plugin.