SEC2-013: The threat model's list of what stays a person's own on a shared record omits the contacts they add #955

Closed
opened 2026-10-17 10:38:11 +00:00 by tiagoagueda · 0 comments
Owner

Found on 2026-10-16 in a read-only security review of postulo at 56fc9d531, checked by a second, independent pass.

Severity: Informational · Category: Authentication/Authorization · Reference: CWE-1059 (Insufficient Technical Documentation); OWASP A04:2021 (Insecure Design)

Location:

  • docs/THREAT-MODEL.md:14 (the sentence "A person's notes, their decision about a listing, its history and their applications are theirs whatever is shared")
  • src/postulo/api/routers/companies.py:271-276 (add_contact on a read grant)
  • tests/security/test_sharing_sweep.py:76-85 (API_READ holds postulo-api:add_contact)

Issue

The threat model promises that "a read-only grant reaches no address that changes a record" and names what a person keeps of their own on a shared record: notes, decision, history, applications. The code and the sharing sweep also let a read-only grantee add a contact at a shared company (add_contact looks the company up with read access and creates a Contact owned by the caller), and that contact is theirs: the company's owner does not see it (_detail prefetches Contact.objects.visible_to(owner)), and test_shared_leaks.py protects the owner's own private contact the same way. The behaviour is consistent; the sentence that explains it is not complete, so a reader of the threat model reads "adds a contact to somebody else's company on a read-only grant" as a breach when it is the design.

Impact

None in code. A documentation gap that invites a false finding, or a future change that "fixes" the design in one place and not the other.

Fix

Extend the sentence at docs/THREAT-MODEL.md:14 to "A person's notes, their decision about a listing, its history, their applications and the contacts they add at a company are theirs whatever is shared", and say the same in the sharing paragraph of the wiki's Sharing page if it lists them. Done when the sentence names contacts and tests/security/test_sharing_sweep.py's module docstring (:8-10) lists them beside the decision, the history and the application.

#896 (closed) - the sharing design this sentence describes.

Found on 2026-10-16 in a read-only security review of `postulo` at `56fc9d531`, checked by a second, independent pass. **Severity:** Informational · **Category:** Authentication/Authorization · **Reference:** CWE-1059 (Insufficient Technical Documentation); OWASP A04:2021 (Insecure Design) **Location:** - `docs/THREAT-MODEL.md:14` (the sentence "A person's notes, their decision about a listing, its history and their applications are theirs whatever is shared") - `src/postulo/api/routers/companies.py:271-276` (`add_contact` on a read grant) - `tests/security/test_sharing_sweep.py:76-85` (`API_READ` holds `postulo-api:add_contact`) ## Issue The threat model promises that "a read-only grant reaches no address that changes a record" and names what a person keeps of their own on a shared record: notes, decision, history, applications. The code and the sharing sweep also let a read-only grantee *add a contact* at a shared company (`add_contact` looks the company up with read access and creates a `Contact` owned by the caller), and that contact is theirs: the company's owner does not see it (`_detail` prefetches `Contact.objects.visible_to(owner)`), and `test_shared_leaks.py` protects the owner's own private contact the same way. The behaviour is consistent; the sentence that explains it is not complete, so a reader of the threat model reads "adds a contact to somebody else's company on a read-only grant" as a breach when it is the design. ## Impact None in code. A documentation gap that invites a false finding, or a future change that "fixes" the design in one place and not the other. ## Fix Extend the sentence at `docs/THREAT-MODEL.md:14` to "A person's notes, their decision about a listing, its history, their applications and the contacts they add at a company are theirs whatever is shared", and say the same in the sharing paragraph of the wiki's *Sharing* page if it lists them. Done when the sentence names contacts and `tests/security/test_sharing_sweep.py`'s module docstring (`:8-10`) lists them beside the decision, the history and the application. ## Related #896 (closed) - the sharing design this sentence describes.
tiagoagueda added this to the 1.0.0 milestone 2026-10-17 10:38:13 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Postulo/postulo#955
No description provided.