SEC2-077: Plain http is allowed to every *.local host, not only to this machine, and the settings hint says otherwise #34

Closed
opened 2026-10-17 10:40:12 +00:00 by tiagoagueda · 0 comments
Owner

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

Severity: Informational · Category: Configuration · Reference: CWE-319 (Cleartext Transmission of Sensitive Information); OWASP A02:2021 (Cryptographic Failures)

Location:

  • src/lib/api.js:39-42
  • src/options.html:14 (instanceHint: "https, unless it runs on this machine")
  • test/api.test.mjs:28-30

Issue

const local = ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname) || url.hostname.endsWith(".local");
if (url.protocol !== "https:" && !local) {
  throw new Refusal("httpsOnly");
}

The exemption from https covers any mDNS name (pi.local, a Postulo on another machine of the
home network), and the test at test/api.test.mjs:29 shows this is intended. The hint beside the
field and PRIVACY.md describe the exemption as "this machine". With an http://…local instance
the bearer token, the captured pages and the pictures of them cross the local network in clear,
and anyone on that path can also answer as the instance, including the addresses the extension
later opens in its review window.

Impact

A person who reads the hint believes the token never leaves their machine unencrypted when it
crosses their LAN. No remote exposure; a deliberate trade-off that the wording does not state.

Fix

Either narrow the exemption to loopback (localhost, 127.0.0.1, [::1]) and let a .local
instance be reached over https like any other, or keep it and say it: change instanceHint to
"https, unless it runs on this machine or on your own network (.local)", and add the sentence to
PRIVACY.md under "What it sends, and where".

Done when the hint, the privacy policy and test/api.test.mjs:29 agree.

Found on 2026-10-16 in a read-only security review of `postulo-chromium` at `b6c1009`, checked by a second, independent pass. **Severity:** Informational · **Category:** Configuration · **Reference:** CWE-319 (Cleartext Transmission of Sensitive Information); OWASP A02:2021 (Cryptographic Failures) **Location:** - `src/lib/api.js:39-42` - `src/options.html:14` (`instanceHint`: "https, unless it runs on this machine") - `test/api.test.mjs:28-30` ## Issue ```js const local = ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname) || url.hostname.endsWith(".local"); if (url.protocol !== "https:" && !local) { throw new Refusal("httpsOnly"); } ``` The exemption from https covers any mDNS name (`pi.local`, a Postulo on another machine of the home network), and the test at `test/api.test.mjs:29` shows this is intended. The hint beside the field and `PRIVACY.md` describe the exemption as "this machine". With an `http://…local` instance the bearer token, the captured pages and the pictures of them cross the local network in clear, and anyone on that path can also answer as the instance, including the addresses the extension later opens in its review window. ## Impact A person who reads the hint believes the token never leaves their machine unencrypted when it crosses their LAN. No remote exposure; a deliberate trade-off that the wording does not state. ## Fix Either narrow the exemption to loopback (`localhost`, `127.0.0.1`, `[::1]`) and let a `.local` instance be reached over https like any other, or keep it and say it: change `instanceHint` to "https, unless it runs on this machine or on your own network (`.local`)", and add the sentence to `PRIVACY.md` under "What it sends, and where". Done when the hint, the privacy policy and `test/api.test.mjs:29` agree.
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-chromium#34
No description provided.