SEC2 index: security review of 2026-10-16 (86 issues across the core, plugins and extensions) #992
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
performance
security
tier
1
tier
2
tier
3
tier/4
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Postulo/postulo#992
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?
Index of the security review of 2026-10-16 (second review,
SEC2-NNN), read-only, every finding checked by a second independent pass before filing. Core at56fc9d531; plugin and extension repos at their heads of 2026-10-10 to 2026-10-12.Earlier reviews, not repeated here: the audit of 2026-09-15 (#215-#241), the review of 2026-09-29 (#354-#645 and the plugin repos) and the security audit of 2026-10-10 (#730-#827, index #828).
Count
Issues
postulo/postulo
High
Medium
Low
POSTULO_PUBLIC_URL, undoing the rule #747 set (Configuration)ATTENDEE, against the form's promise (Data Exposure)http://receiver, so notification text leaves in clear (Data Exposure)POSTULO_BACKUP_DOWNLOADfalls open to "every administrator" on any value it does not recognise, and no start-up check reads it (Configuration)postulo.log(Data Exposure)|safe, against the project's own #806 rule (Injection)Informational
read_wheelreads a wheel's metadata members without a size cap (Input Validation)templates/directory is searched before every app-directory template, contrary to whatthemes.pypromises (Configuration)X-Request-IDis dropped (Configuration)/healthztreats a request as forwarded only onX-Forwarded-For, so behind a loopback proxy every visitor is a "probe" (Data Exposure)seed_demo --passwordtakes a password on the command line (Configuration)hx-valsJSON by text interpolation rather than JSON encoding (Injection)postulo/postulo-apprise
Medium
body_format, so HTML services receive a captured page's words as markup (Injection)Low
postulo/postulo-chromium
Low
npm audit(Dependencies)captureswithout a word, so the threat model's bound on a leaked extension token is unchecked (Authentication/Authorization)Informational
*.localhost, not only to this machine, and the settings hint says otherwise (Configuration)review_url,listing_url) are opened in the review window without an instance-origin check (Input Validation)shipped()lets a catalogue key override the build'slanguageTaganddirection(Input Validation)postulo/postulo-dav
Low
href(Injection)postulo/postulo-firefox
Low
npm audit(Dependencies)Informational
check-pin.mjsaccepts a tag name as the pin, and a tag can be moved (Configuration)postulo/postulo-helloworld
Low
Informational
test()echoes theOSErrortext, server-side path included, to the account holder (Data Exposure)postulo/postulo-imap
Low
postulo/postulo-mcp
Low
install.shwith no version and no checksum; the core fixed this in #790 (Configuration)Informational
Postulo._callreads every answer whole, with no size ceiling and no deadline for the whole exchange (Input Validation)postulo/postulo-paperless
Low
postulo/postulo-templates
Low
curl | shand audits no dependency, and no existing issue names this repository (Configuration)postulo/postulo-thunderbird
Low
npm audit(Dependencies)Informational
capturestoken, while the threat model's mail-client row promiseslistings:bindand nothing else (Authentication/Authorization)api.js(Dependencies)storage.localin clear, outside Thunderbird's primary password, and the privacy text does not say so (Data Exposure)tiagoagueda/postulo-francetravail
Five issues filed on that private repository and listed there.
Highest priority
Also done
_explain).security, since a read-only share can reachapply_card.Not filed
The second pass dropped: a merge refusal on trailed or shared records (a functional bug with no security consequence), document PDFs drawn without a deadline (outside the threat model), a per-account upload quota (already #268), and CI items that follow the project's documented action-pinning policy (#790).
All 86 issues of this review are closed, so this index is done.
How they were fixed (all through pull requests, each with its CI green before it merged):
read_body,deadline_in,untilandBodyRefusedon the plugin API), #1000 (API), #1010 (the remaining 13).Left open on purpose, none of them security findings of this review: postulo-dav#6, #11 and #13 (they wait on core #325, #326, #327, #330 and #332), the rest of postulo-apprise#13 (the CI audit for the other repositories), and the two feature issues of the France Travail plugin.
Follow-ups that are the operator's, not code: re-sign
catalogue/official/index.json(the signer now writes a 60-day expiry), runscripts/weblate.py configureto add thesafe-htmlcheck, and dispatch the Dependencies workflow once to prove its two-job split.New decisions recorded in the threat model: the capture-API refusal wording (#954), and what a read-only grantee may add on a shared record (#955).