Privacy review, on request by a colleague
Build LinkLog Development Image / development-image (push) Successful in 43s

This commit is contained in:
Olaf
2026-09-15 21:09:52 +02:00
parent 24c4753093
commit 370a91b23b
3 changed files with 158 additions and 0 deletions
+148
View File
@@ -0,0 +1,148 @@
# LinkLog Firefox Extension Privacy Validation
Date: 2026-09-15
## Scope
This report validates the privacy-relevant properties of the Firefox extension in `webextension/` only. It does not treat the LinkLog backend as part of the extension, except where the extension explicitly sends data to the user-configured backend.
## Validation Method
- Reviewed the extension manifest, popup and options scripts, localized privacy text, and packaged-page HTML.
- Searched the extension source for storage, permission, tab-capture, cookie, history, clipboard, and network APIs.
- Ran `python3 scripts/release/validate_release.py` to confirm the checked-in signed XPI and Firefox disclosure metadata are consistent.
## Summary
The extension's implemented privacy behavior is mostly consistent with its declared purpose:
- It does not include telemetry, analytics, adtech, crash reporting, or third-party beaconing.
- It captures website activity only from the active tab when the user opens the popup.
- It stores long-lived account metadata locally, but keeps bearer session credentials in Firefox session storage rather than persistent extension storage.
- It sends captured link data only to the user-selected backend, plus standard extension-update traffic to the configured self-update URL.
- Firefox privacy disclosure metadata is present and validated for the signed XPI.
The main residual privacy risk is that the extension accepts both `http` and `https` backend URLs. That is useful for local development, but a non-local HTTP backend would expose credentials and saved-link data in transit.
## Verified Properties
### 1. Declared Firefox permissions are narrow
- Required permissions are limited to `activeTab` and `storage`.
- Host access is not pre-granted broadly at install time. Instead, the extension declares optional HTTP and HTTPS host permissions and requests access only for the specific backend origin entered by the user.
- The signed-release validator enforces the Firefox `data_collection_permissions` declaration of required `websiteActivity` and no optional data-collection categories.
Assessment: consistent with a least-privilege model for a link-saving extension.
### 2. Website activity access is limited to the active tab
- The popup reads the current page title and URL via `browser.tabs.query({ active: true, currentWindow: true })`.
- No content scripts are injected into visited pages.
- No background/service-worker logic observes browsing continuously.
Assessment: the extension collects the minimum page context needed for its stated function when the user explicitly opens the popup.
### 3. Local storage use is bounded and understandable
Persistent local storage:
- `backendUrl`
- `email`
- `username`
Session-scoped storage:
- `accessToken`
- `refreshToken`
- `tokenExpiresAt`
- `deviceId`
Observed behavior:
- Access and refresh credentials are stored in `browser.storage.session`.
- Sign-out and token invalidation clear those session values and also remove older legacy token keys from `browser.storage.local`.
- Account-identifying metadata remains in persistent storage to preserve configuration across browser restarts.
Assessment: token persistence is minimized appropriately, but the extension still retains backend/account metadata locally until changed or removed.
### 4. Outbound network traffic is limited and attributable
User-configured backend traffic:
- `POST /api/auth/login`
- `POST /api/auth/refresh`
- `POST /api/auth/logout`
- `GET /api/auth/me`
- `GET /api/tags`
- `GET /api/public/config`
- `GET /api/user/plugins/mastodon`
- `GET /api/links/check`
- `GET /api/scrape`
- `POST /api/links`
What the extension sends to the backend:
- Sign-in credentials: email, password, optional OTP.
- Session tokens in `Authorization` headers after login.
- Link payloads: title, cleaned URL, comment, timestamp, and tags.
- Lookup values for duplicate detection and title scraping.
Other network destinations:
- Firefox self-update metadata and signed XPI download are configured via `webextension/updates.json` and the manifest `update_url` at `git.kolkman.org`.
- Repository links in the popup and options page go to `git.kolkman.org` only when the user clicks them.
Assessment: no hidden third-party data sinks were found in the extension code.
### 5. The extension avoids higher-risk browser APIs
No use was found of:
- cookies APIs
- browsing history APIs
- bookmarks APIs
- clipboard APIs
- native messaging
- remote script loading
- `XMLHttpRequest` or `sendBeacon`
Assessment: this reduces both privacy scope and accidental data leakage paths.
### 6. Packaged extension pages use a restrictive CSP
- Extension pages declare `script-src 'self'; object-src 'none'`.
- Popup and options pages load only bundled local scripts and assets.
Assessment: this materially lowers the risk of third-party script injection into extension pages.
### 7. The privacy notice is broadly accurate, with one caveat
The options page says the extension does not collect personal data beyond what is necessary to log links to the LinkLog server. That statement is broadly supported by the code, because the extension only stores and transmits data needed for authentication and link submission.
Caveat: the notice would be more precise if it explicitly mentioned that the extension stores the configured backend URL, email address, and username locally, and stores session credentials for the current browser session.
## Residual Privacy Risks
### R1. Non-TLS backends are allowed
The extension accepts `http` and `https` backend URLs. For local development this is reasonable, but for non-local use it means login credentials, tokens, titles, URLs, comments, timestamps, and tags can be transmitted without transport encryption.
Recommendation: enforce `https` for non-localhost backends, or at minimum warn before allowing a non-TLS backend.
### R2. Backend publication and retention are outside extension control
The extension's privacy behavior ends once data is sent to the configured LinkLog server. The backend may publish links publicly, combine them with user profile data, retain them, or forward them through enabled plugins such as Mastodon.
Recommendation: keep extension-facing privacy text explicit that saved link data becomes subject to the chosen backend's policies and configuration.
### R3. Persistent local account metadata is not cleared on sign-out
Sign-out clears session credentials, but leaves `backendUrl`, `email`, and `username` in persistent extension storage for convenience.
Recommendation: this is a reasonable default, but the UI could offer a separate "forget this account on this browser" action.
## Overall Conclusion
The Firefox extension has a relatively narrow privacy footprint and largely follows least-privilege principles. Its privacy disclosure about website activity is implemented and release-validated, session tokens are kept in session storage, and no unexpected telemetry or third-party exfiltration paths were found in the extension code.
The most important remaining privacy improvement is to prevent or strongly discourage non-HTTPS backends outside local development.
+6
View File
@@ -151,6 +151,12 @@ Run full backend and frontend test suites.
### Assistant outcome
The normal backend suite passed with 46 tests. Frontend and extension validation passed for all JavaScript syntax checks, JSON files, XPI rebuild, and unsigned XPI validation. The warnings-as-errors backend variant failed on unclosed SQLite connection `ResourceWarning` instances under Python 3.13; no functional tests failed.
### User
Validate the Privacy properties of the firefox plugin specifically and report them in Privacy.md
### Assistant outcome
Added `Privacy.md` with a plugin-specific privacy validation covering manifest permissions, active-tab capture scope, local and session storage, outbound network destinations, Firefox `data_collection_permissions`, release validation, and residual privacy risks. Confirmed the signed XPI release metadata validates successfully and identified non-HTTPS backend support as the main remaining privacy caveat.
### User
Address SA-007 and use linklog.example.com as default LINKLOG_PUBLIC_URL.
+4
View File
@@ -318,6 +318,10 @@ If the user uses the filters and/or search in the toolbox then those should limi
259. Make sure the CHANGELOG reflects all changes since commit 74b2c400c6
260. Add a skill to maintain the changelog.md
261. In the new-entry form, provide a warning when the total ammount of characters is over LINKLOG_MAX_POST_CHARACTERS=500 (also indicat the number of characters used/500 count). This is to prevent Mastodon posts from failing - so all characters should be counted.
## 2026-09-15
262. Validate the Privacy properties of the firefox plugin specifically and report them in Privacy.md
262. Implement the same functionality in the firefox plugin
## 2026-09-07