PST-090: The catalogue wheel download names its temporary file from the release URL's last path segment #819
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
performance
security
tier
1
tier
2
tier
3
tier/4
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Postulo/postulo#819
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 in the security audit of 2026-10-10 (
SECURITY-AUDIT-2026-10-10.md), run againstmainatc30851bfrom 8 to 10 October 2026, as PST-090. Severity: Informational.The text below is the audit's entry, unchanged apart from links to the other issues it names. The finding was produced by automated review and checked by a second automated pass; re-check it before acting on it.
src/postulo/plugins/catalogue.py(358,371)Who can do it, and what they need. The publisher of a plugin catalogue the administrator has configured (URL plus Ed25519 key), or somebody holding that publisher's signing key. Precondition: an administrator presses Install for a release of that catalogue.
How it works.
/..or/.(or has no path at all).Impact. An unhandled 500 on an administrator action from a source that is already trusted to deliver code; no write outside the scratch directory was found. Recorded for completeness.
Verification (verdict: confirmed; severity after verification: Informational). Correction: 'or has no path at all' is wrong;
https://wheels.exampleyields a file named 'wheels.example' (tested, no failure); the 'plugin.whl' fallback only applies to a URL that is empty after stripping slashes. The more useful framing is that catalogue.install has no handler around download() at all: an unreachable wheel host (httpx.ConnectError) and a refused destination (http.DestinationRefused) also produce a 500 on the same admin action (tested: both returned 500). Remediation: catch httpx.HTTPError, http.DestinationRefused and OSError in install()/download() and re-raise as CatalogueError; build the temp name from a fixed 'plugin.whl' or from the validated wheel filename.Suggested remediation. Name the download yourself (e.g. a random token plus .whl, as the upload path does with secrets.token_urlsafe) rather than from the URL, and catch OSError around the write as a CatalogueError.
Fixed in
12bef18ccon main.