Capture API: a captures token can ask which postings the person holds and their state, which the threat model denies #536
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#536
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-09-29 in a read-only review of postulo at
95348908d, reading every route thecapturesscope opens against whatdocs/THREAT-MODEL.mdsays it opens.Checked again on 2026-10-01 against
mainat0a5cad587: still present. The code is now atapi/api.py:761(known_captures; itslisting()helper at:772-780,stateat:778) andapi/api.py:287(KnownIn.postings);jobs/known.py,api/models.py:30anddocs/THREAT-MODEL.md:20have not moved.The threat model says an extension's token "holds
capturesand nothing else, so the worst it can do is fill a review queue the person will decline", and that "it can send a page and cannot read one back". ButPOST /captures/known, under the same scope, answers questions about the person's listings: for up to 100 postings per request it returns every matching listing's title, company name, address, state (applied,discardedand so on) and creation time. The extension reads only the title, the creation time and the link, so the state, the company name and the address are handed out for nothing, and the documents describe a narrower scope than the code grants.api/api.py:759known_captures(itslisting()helper at:770-778returnsstateat:776);api/api.py:285KnownIn.postings(max_length=100);jobs/known.py:57-88known(matches by address, and by exact title plus company);docs/THREAT-MODEL.md:20;api/models.py:30("captures": _("Capture postings")); the wiki's The capture API page, the scope table at line 21 and the paragraph at lines 27-28. The extension's use issayKnownin postulo-chromiumsrc/popup.js:208-236.GET /capturesalso lists the captures awaiting review, which the wiki does mention.capturestoken, such as a copied browser profile or a compromised update of the extension. They can only confirm postings they can name, not list them all.listings:bindscope is described precisely ("a title, a company, a place and a state"); this one is not.id,title,created_atandlisting_url), withoutstate,company_nameandurl. Then correctdocs/THREAT-MODEL.md:20, thecaptureslabel inSCOPESand the wiki's scope table and paragraph so they say that the scope also answers whether a posting the caller names is already held, with its title and date.Done when
tests/test_known.pyasserts that the answer for a held listing carries nostate,company_nameorurlkey, and the threat model and the scope's label name the lookup.