Reproducible builds pinned to a chromium release, a real minimum version, store paperwork, and small hardening for both extensions #1

Closed
opened 2026-09-15 21:23:48 +00:00 by tiagoagueda · 0 comments
Owner

Found in the 2026-09-15 audit of the plugin repositories. This issue covers both browser extensions: the Firefox build wraps postulo-chromium, so the fixes land in both repositories. The extension itself is well built: MV3, activeTab, host permission only as an optional per-instance request, no content scripts, no inline script, nothing passed to innerHTML, a log that never records the token, and 115 keys complete in 39 locales.

postulo-firefox

  1. The build tracks a moving branch. source.json:3 has "ref": "main", and scripts/build.mjs:20-21 clones over the network at build time. AMO source submissions are therefore not reproducible, and the two extensions drift: the local .source checkout is at 14653e5, older than chromium's 08774a2.
    → Pin a tag or commit SHA, and check in CI that the pin equals chromium's latest tag.
  2. The minimum version doesn't match the manifest. manifest.json:46-51 sets strict_min_version 128.0 alongside data_collection_permissions, which Firefox supports only from about 140 (Android 142).
    → Raise the minimum, and let web-ext lint confirm it.
  3. CI uses the deprecated upload-artifact@v3 with continue-on-error.
    → Update it, and add a tag workflow that produces the signed, zipped artifact.

postulo-chromium (and both stores)

  1. No privacy policy page. The README has a privacy paragraph (README.md:19), but the Chrome Web Store requires a standalone policy URL for extensions that handle authentication and page content, and AMO asks too.
    → PRIVACY.md published at a stable URL, stating what is stored (the instance address and token, in storage.local, unencrypted, as browsers offer), what is sent and where, and that nothing else is collected. Add store listing assets.
  2. unlimitedStorage is broader than needed. It exists to keep captured page HTML.
    → Cap stored HTML per capture and drop the permission.
  3. No explicit CSP.
    → content_security_policy.extension_pages: "script-src 'self'; object-src 'none'", so the default can't loosen silently.
Found in the 2026-09-15 audit of the plugin repositories. This issue covers both browser extensions: the Firefox build wraps `postulo-chromium`, so the fixes land in both repositories. The extension itself is well built: MV3, `activeTab`, host permission only as an optional per-instance request, no content scripts, no inline script, nothing passed to `innerHTML`, a log that never records the token, and 115 keys complete in 39 locales. ## postulo-firefox 1. **The build tracks a moving branch.** `source.json:3` has `"ref": "main"`, and `scripts/build.mjs:20-21` clones over the network at build time. AMO source submissions are therefore not reproducible, and the two extensions drift: the local `.source` checkout is at `14653e5`, older than chromium's `08774a2`. → Pin a tag or commit SHA, and check in CI that the pin equals chromium's latest tag. 2. **The minimum version doesn't match the manifest.** `manifest.json:46-51` sets `strict_min_version 128.0` alongside `data_collection_permissions`, which Firefox supports only from about 140 (Android 142). → Raise the minimum, and let `web-ext lint` confirm it. 3. **CI** uses the deprecated `upload-artifact@v3` with `continue-on-error`. → Update it, and add a tag workflow that produces the signed, zipped artifact. ## postulo-chromium (and both stores) 4. **No privacy policy page.** The README has a privacy paragraph (`README.md:19`), but the Chrome Web Store requires a standalone policy URL for extensions that handle authentication and page content, and AMO asks too. → `PRIVACY.md` published at a stable URL, stating what is stored (the instance address and token, in `storage.local`, unencrypted, as browsers offer), what is sent and where, and that nothing else is collected. Add store listing assets. 5. **`unlimitedStorage` is broader than needed.** It exists to keep captured page HTML. → Cap stored HTML per capture and drop the permission. 6. **No explicit CSP.** → `content_security_policy.extension_pages: "script-src 'self'; object-src 'none'"`, so the default can't loosen silently.
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-firefox#1
No description provided.