PST-035: API token creation needs no re-authentication, defaults to never expiring and is not rate-limited #764
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#764
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-035. Severity: Low.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/api/views.py(437-466)Who can do it, and what they need. Someone with momentary control of a signed-in session: an unattended unlocked browser, or a stolen session cookie. Precondition: a live session; CSRF protection and the CSP already stop a cross-site page from doing this.
How it works.
/capture-tokens/new/with name, scopesread,write,documents:read,captures,listings:bindand expiry left at its default 'Never'.Impact. Converts a transient session compromise into a durable, full-scope API credential (every document downloadable under
documents:read). Standard for many APIs, but the application otherwise treats tokens as the most sensitive thing it mints.Evidence.
Verification (verdict: confirmed; severity after verification: Low). Line numbers were wrong: ApiTokenCreateView.post is src/postulo/api/views.py:45-61 (issue call at :50-55), and EXPIRY_CHOICES / the expires field are src/postulo/api/forms.py:9-14 and :32. Precondition: a live session, i.e. an unattended unlocked browser or a stolen session cookie, which the threat model largely treats as out of scope. Impact: durable, full-scope credential that survives sign-out and password change. Remediation: wrap ApiTokenCreateView.post in reauthentication_required as account deletion and backups are, consider a default or maximum expiry, and revoke or flag tokens on password change and from an account-security notice.
Suggested remediation. Require re-entering the password (or a recent-authentication window, as allauth's reauthentication flow provides) before issuing a token; default the expiry to a finite period; revoke or at least flag tokens on password change and show the number of live tokens on the security settings page.
Fixed in
c34e21966on main.