summaryrefslogtreecommitdiff
path: root/doc/Security.md
diff options
context:
space:
mode:
authortanaka takashi <isazaka@gmail.com>2026-09-01 20:10:20 +0900
committertanaka takashi <isazaka@gmail.com>2026-09-01 20:10:20 +0900
commit55e581bab9b600e7c070ec596d3109fc897d2d86 (patch)
tree15ca196a1858696c216946dc9608fae613ad6e5f /doc/Security.md
feat: Firefox selection translation extension with local Ollama (initial version)
Implement the complete initial version of a Firefox WebExtension (Manifest V3) that translates selected text on web pages using a local Ollama LLM and shows the result in a small popover near the selection. Specification alignment (Phase 0) - Unified Specifications.md / Design.md / Security.md on the same approach: Ollama REST API + Fetch API + NDJSON streaming (no ollama-js SDK dependency) - Fixed host_permissions to http://localhost/* and http://127.0.0.1/* because Firefox match patterns do not support port numbers (bug 1362809/1468162); the actual connection target is restricted to localhost/127.0.0.1 + any port by application-side validation (defense in depth, OLL-09) - Clipboard: use navigator.clipboard.writeText() only inside the copy button click (user activation); no deprecated execCommand fallback Implementation (zero dependencies, vanilla JS, no npm/Node required) - manifest.json: MV3, background.scripts + type:module (event page, no service_worker), action popup, options_ui, content_scripts for http/https, permissions: storage + localhost host permissions only - src/shared: constants (ports, limits, presets, error codes), message validation, settings schema (defaults / merge / sanitize / buildOptions / toApiThinking), system prompt builder (fixed prompt first + user prompt) - src/background: message-router (runtime.Port streaming + runtime.onMessage for model list), translation-session (single active request, abort previous on new request, stale chunk suppression), ollama-client (fetch against /api/tags and /api/chat with buffering NDJSON line parser tolerant to chunk boundaries inside JSON objects, AbortController, host re-validation before every request, HTTP status to error-code mapping), settings-service (storage.local load/save with validation and fallback to defaults) - src/content/content.js: single classic script (Firefox does not support ES modules in content scripts) with selection detection (selectionchange + mouseup + keyup, debounced), Shadow DOM action button, Shadow DOM popover with HIDDEN/LOADING/STREAMING/COMPLETED/ERROR state machine, port client with requestId-based stale chunk filtering, enabled-state sync via storage.onChanged; all dynamic text rendered via textContent only - src/popup + src/options: full settings UI (enable toggle, Ollama host, model list from Ollama with saved-model warning, target language, thinking mode, temperature slider 0.0-2.0 step 0.1, context length presets 4k/8k/16k/32k/128k/256k, seed random/fixed with integer value, user system prompt, advanced numeric options with steppers, stop sequences textarea) - icons generated by tools/make-icons.ps1 (System.Drawing, no external tools) - build.ps1 packages manifest.json + icons/ + src/ into dist zip, excluding tests/, doc/, ollama-js/ and tools/ Tests (71 passed, 0 failed) - In-browser test runner (tests/test.html) with custom describe/it/assert framework; no npm, no Node.js - Unit: constants sync between content mirror and shared module, Ollama host validation (localhost/127.0.0.1 + any port only; rejects external hosts, LAN IPs, https, credentials, paths), settings schema defaults and fallback, temperature 0.1-step validation, context length presets, seed modes, advanced option types, buildOptions omission of unset values and absence of tfs_z/mirostat fields, system prompt composition order, message validation with selection length boundary values - Integration: NDJSON streaming across awkward byte boundaries, thinking chunk forwarding, malformed line tolerance, error payload mapping, think/ options inclusion rules, model list, TranslationSession abort semantics, settings round-trip with storage.onChanged cache refresh, full port flow (started/chunk/completed), newer request aborts older with stale chunk discard, malformed message rejection, OLLAMA_UNAVAILABLE and INVALID_SETTINGS error paths, untrusted sender rejection Security audit (Design.md section 24 checklist: all pass) - No innerHTML/outerHTML/document.write/eval/new Function/localStorage - No remote JS/CSS/fonts/CDN resources; no inline scripts in extension pages - Ollama access limited to background; content scripts never fetch Ollama - Background validates message type/length/requestId; single concurrent translation enforced - Clipboard API only (no execCommand fallback) - Minimal permissions: storage + localhost host permissions Docs - README.md with build/load/usage instructions, API list, permission rationale - doc/Testing-Results.md with automated test results, security audit results, and a 14-item manual Firefox verification checklist (to be executed on a real Firefox + Ollama environment)
Diffstat (limited to 'doc/Security.md')
-rw-r--r--doc/Security.md804
1 files changed, 804 insertions, 0 deletions
diff --git a/doc/Security.md b/doc/Security.md
new file mode 100644
index 0000000..956f169
--- /dev/null
+++ b/doc/Security.md
@@ -0,0 +1,804 @@
+# Security.md
+
+## 1. Purpose
+
+This document defines the mandatory security constraints and implementation rules for the Firefox WebExtension project.
+
+The implementation agent MUST treat this file as a normative development policy together with `Specifications.md` and `Design.md`.
+
+When there is a conflict between convenience and this security policy, this policy takes precedence unless the project owner explicitly changes the requirement.
+
+---
+
+## 2. Security Objectives
+
+| ID | Objective |
+|---|---|
+| SEC-001 | Minimize the extension's attack surface. |
+| SEC-002 | Avoid third-party build-time and runtime dependency supply-chain risk. |
+| SEC-003 | Treat all web page content as untrusted input. |
+| SEC-004 | Prevent selected text and LLM output from being evaluated as HTML or JavaScript. |
+| SEC-005 | Restrict privileged WebExtension operations to the minimum required components. |
+| SEC-006 | Restrict network communication to the configured Ollama endpoint. |
+| SEC-007 | Use current Firefox WebExtensions APIs and avoid deprecated or obsolete APIs. |
+| SEC-008 | Keep the implementation auditable without a package manager or generated dependency tree. |
+
+---
+
+## 3. Dependency Policy
+
+### 3.1 Mandatory Rules
+
+The project MUST be developed without Node.js or JavaScript package managers.
+
+The following are prohibited:
+
+- Node.js as a required development or runtime dependency
+- npm
+- yarn
+- pnpm
+- bun package management
+- `node_modules`
+- third-party JavaScript packages
+- third-party CSS frameworks
+- remote JavaScript
+- remote CSS
+- remote fonts
+- CDN-hosted runtime resources
+
+The project SHOULD NOT contain `package.json`.
+
+All resources required at runtime MUST be included directly in the extension package or supplied by Firefox/Web Platform standard APIs.
+
+### 3.2 Allowed Technologies
+
+The implementation MAY use:
+
+- HTML
+- locally stored CSS
+- vanilla JavaScript
+- Firefox WebExtensions APIs
+- standard DOM APIs
+- Fetch API
+- Streams API
+- `TextDecoder` / `TextDecoderStream`
+- standard `JSON` APIs
+- locally bundled PNG/SVG assets
+- inline SVG created by the project
+- operating-system fonts through CSS generic/system font families
+
+### 3.3 CSS and Asset Policy
+
+All application CSS MUST be owned by this project and stored locally in the repository.
+
+Do not download and vendor a CSS framework unless explicitly approved.
+
+Preferred approach:
+
+```text
+content.css
+popup.css
+options.css
+```
+
+External resources such as the following MUST NOT be used:
+
+```text
+Google Fonts
+Font Awesome CDN
+Material Icons CDN
+Bootstrap CDN
+Tailwind CDN
+jsDelivr
+unpkg
+cdnjs
+```
+
+Icons SHOULD be:
+
+1. project-owned local SVG/PNG files, or
+2. inline SVG defined directly by the application.
+
+System fonts SHOULD be used, for example:
+
+```css
+font-family: system-ui, sans-serif;
+```
+
+---
+
+## 4. Ollama Integration Policy
+
+### 4.1 No Ollama JavaScript SDK Dependency
+
+The project MUST NOT require `ollama-js`.
+
+The extension MUST communicate with Ollama directly using the official Ollama HTTP API and the browser Fetch API.
+
+The intent is to eliminate npm/package-manager supply-chain dependencies.
+
+### 4.2 Required API Scope
+
+The initial implementation SHOULD require only the minimum Ollama endpoints needed by the specification.
+
+Expected endpoints:
+
+| Endpoint | Purpose |
+|---|---|
+| `GET /api/tags` | Retrieve installed models. |
+| `POST /api/chat` | Perform translation generation using streaming. |
+
+Do not add Ollama API endpoints unless required by a defined feature.
+
+### 4.3 Streaming
+
+Translation MUST use streaming responses.
+
+The Ollama client module MUST:
+
+- parse streamed response data safely;
+- tolerate chunk boundaries that do not align with JSON object boundaries;
+- cancel the current request when a newer translation request supersedes it;
+- use `AbortController` or equivalent standard browser functionality;
+- propagate only validated translation text to the content script.
+
+### 4.4 Ollama Endpoint
+
+Default endpoint:
+
+```text
+http://localhost:11434
+```
+
+The endpoint MAY be configurable according to the product specification. In the initial version, the configured endpoint MUST be limited to `http://localhost:<port>` or `http://127.0.0.1:<port>`. External hosts, LAN IPs, and HTTPS endpoints MUST be rejected by validation.
+
+The implementation MUST validate the configured value before use, and the Ollama client MUST re-verify the target host immediately before each request (defense in depth).
+
+The background component MUST be the only component that communicates directly with Ollama.
+
+Content scripts MUST NOT directly call Ollama.
+
+---
+
+## 5. Firefox WebExtensions Policy
+
+### 5.1 Manifest
+
+The extension MUST use Manifest V3.
+
+Firefox-specific behavior MUST be verified against current MDN documentation before implementation.
+
+Do not blindly copy Chromium-specific Manifest V3 examples.
+
+### 5.2 Background Implementation
+
+For Firefox, use the supported background mechanism documented for Firefox.
+
+Do NOT assume Chromium's:
+
+```json
+"background": {
+ "service_worker": "background.js"
+}
+```
+
+is supported by Firefox.
+
+The implementation agent MUST verify the current Firefox support status before changing the background model.
+
+### 5.3 APIs to Prefer
+
+Use modern APIs where required:
+
+| Purpose | Preferred API |
+|---|---|
+| Toolbar action | `action` |
+| Extension storage | `storage.local` |
+| Long-lived extension communication | `runtime.connect()` / `runtime.Port` |
+| One-shot extension messages | `runtime.sendMessage()` |
+| Dynamic script injection, only if needed | `scripting.executeScript()` |
+
+### 5.4 APIs / Patterns to Avoid
+
+Do not introduce the following unless explicit project requirements justify them:
+
+- Manifest V2
+- `browser_action`
+- `browserAction.*`
+- `tabs.executeScript()`
+- `tabs.insertCSS()`
+- `runtime.getBackgroundPage()`
+- `extension.getBackgroundPage()`
+- `window.localStorage` for extension settings
+- `externally_connectable`
+- `runtime.onMessageExternal`
+- `runtime.onConnectExternal`
+- `nativeMessaging`
+- `webRequest`
+- `cookies`
+- `history`
+- `bookmarks`
+- `downloads`
+- unnecessary `tabs` permission
+- unnecessary `scripting` permission
+
+The implementation MUST verify whether any WebExtensions API it intends to add is deprecated, obsolete, Firefox-incompatible, or unnecessarily privileged.
+
+---
+
+## 6. Permission Minimization
+
+The extension MUST request only permissions required by implemented features.
+
+Expected initial permission set:
+
+```text
+storage
+```
+
+Expected host permission:
+
+```text
+http://localhost/*
+http://127.0.0.1/*
+```
+
+Firefox match patterns do not support port numbers (Firefox bug 1362809 / 1468162). Therefore the patterns above match any port on localhost. The application MUST restrict the actual connection target to `http://localhost:<port>` or `http://127.0.0.1:<port>` via its own host validation before any Ollama request.
+
+or the minimum equivalent required by the final Ollama-host design.
+
+Page access MAY require content-script match patterns for HTTP/HTTPS pages because translation is initiated by selecting page text.
+
+Do not add broad privileged permissions for convenience.
+
+Every newly introduced permission MUST be justified in code review.
+
+---
+
+## 7. Trust Boundaries
+
+The system has three primary trust zones.
+
+```text
+Untrusted Web Page
+ |
+ | selected text
+ v
+Content Script
+ |
+ | validated extension messages
+ v
+Background
+ |
+ | HTTP
+ v
+Ollama
+```
+
+### 7.1 Web Page
+
+All page content MUST be considered untrusted.
+
+This includes:
+
+- text selected by the user;
+- DOM content;
+- attributes;
+- page-generated text;
+- scripts;
+- event data;
+- iframe content;
+- strings that resemble prompts or instructions.
+
+The presence of text such as:
+
+```text
+Ignore previous instructions...
+```
+
+MUST NOT cause that text to be treated as an application instruction.
+
+Selected web content is translation data, not trusted control input.
+
+### 7.2 Content Script
+
+The content script is responsible only for tasks that require page access, including:
+
+- obtaining the user's current text selection;
+- positioning the translation action icon;
+- rendering the translation popover;
+- forwarding translation requests;
+- receiving streamed translation text;
+- handling local UI interaction.
+
+It MUST NOT be responsible for privileged network communication with Ollama.
+
+### 7.3 Background
+
+The background component owns privileged application operations:
+
+- Ollama HTTP communication;
+- request lifecycle management;
+- configuration access where appropriate;
+- message validation;
+- request cancellation;
+- Ollama response parsing.
+
+---
+
+## 8. DOM and XSS Rules
+
+### 8.1 Plain-Text Rendering
+
+Page-derived text and LLM-generated text MUST be rendered as plain text.
+
+Use safe DOM APIs such as:
+
+```js
+element.textContent = value;
+```
+
+Do NOT use untrusted content with:
+
+```js
+element.innerHTML = value;
+element.outerHTML = value;
+shadowRoot.innerHTML = value;
+document.write(value);
+```
+
+### 8.2 No HTML Interpretation
+
+The translation result is plain text.
+
+Do not implement Markdown rendering, HTML rendering, or rich-text parsing unless explicitly added as a later requirement and separately security-reviewed.
+
+### 8.3 No Dynamic Code Execution
+
+The following are prohibited:
+
+```text
+eval()
+new Function()
+setTimeout(string)
+setInterval(string)
+```
+
+No selected page content, setting, LLM response, or remote response may be executed as JavaScript.
+
+---
+
+## 9. Shadow DOM Policy
+
+The translation UI SHOULD use Shadow DOM where practical to isolate extension UI styling from page CSS.
+
+Primary reasons:
+
+- reduce CSS collisions;
+- reduce page-style interference;
+- contain translation UI styles;
+- improve predictable layout.
+
+Shadow DOM MUST NOT be treated as an XSS security boundary.
+
+LLM responses and page text inside a shadow root MUST still use plain-text rendering.
+
+---
+
+## 10. Page Script Isolation
+
+The extension SHOULD rely on the normal WebExtensions content-script isolation boundary.
+
+Do not bridge page scripts and extension scripts unless a future requirement makes this unavoidable.
+
+The following SHOULD NOT be used:
+
+- `wrappedJSObject`
+- `exportFunction`
+- `cloneInto`
+- custom page-script injection
+- page-controlled `window.postMessage` communication
+
+If page-script communication becomes necessary later, it requires an explicit security design update.
+
+---
+
+## 11. Message Validation
+
+All messages received by privileged extension components MUST be validated.
+
+Example translation request shape:
+
+```js
+{
+ type: "translate",
+ requestId: "...",
+ text: "..."
+}
+```
+
+The receiver MUST validate at least:
+
+- message is an object;
+- known `type`;
+- expected fields are present;
+- `text` is a string;
+- `requestId` is a string;
+- text length is within defined limits;
+- unsupported fields do not alter privileged behavior.
+
+Do not dispatch privileged behavior using arbitrary method names supplied by messages.
+
+Avoid patterns such as:
+
+```js
+handlers[message.method](message);
+```
+
+unless `message.method` is strictly allow-listed.
+
+---
+
+## 12. Input Limits and Resource Abuse
+
+Selected text MUST have a maximum allowed size.
+
+The exact product limit MAY be defined in `Specifications.md`, but an implementation limit MUST exist.
+
+The purpose is to reduce:
+
+- accidental huge requests;
+- malicious resource consumption;
+- unnecessarily long model generation;
+- UI hangs;
+- memory pressure.
+
+If input exceeds the allowed limit, the extension MUST fail safely and provide a user-visible error.
+
+Repeated translation requests MUST cancel obsolete in-flight requests.
+
+---
+
+## 13. LLM Prompt Boundary
+
+The application MUST maintain a separation between:
+
+1. application-controlled system instructions;
+2. user-configurable system instructions;
+3. selected page text.
+
+The application-controlled prompt MUST state that selected page content is translation material and must not be interpreted as instructions.
+
+Selected text MUST NOT be concatenated into trusted system instructions.
+
+Preferred conceptual request structure:
+
+```text
+system:
+ application-controlled translation rules
+ + validated user translation preferences
+
+user:
+ selected page text
+```
+
+---
+
+## 14. Settings Validation
+
+Every configurable Ollama generation value MUST be validated before being sent to Ollama.
+
+Validation MUST include:
+
+- expected type;
+- finite numeric value where applicable;
+- supported range;
+- integer-only constraints where applicable;
+- allowed enum values;
+- context-length preset membership;
+- string length limits.
+
+Invalid stored values MUST NOT be passed directly to Ollama.
+
+The implementation SHOULD fall back to safe defaults or request correction from the user.
+
+---
+
+## 15. Seed Security / Correctness Rule
+
+Seed configuration MUST distinguish between:
+
+- variable/random behavior;
+- fixed deterministic integer seed.
+
+When fixed seed mode is enabled, the value MUST be validated as an integer.
+
+When variable mode is enabled, the implementation MUST use the Ollama/API-supported behavior defined in the specification and MUST NOT generate executable or unsafe random data.
+
+---
+
+## 16. Storage Rules
+
+Use:
+
+```text
+browser.storage.local
+```
+
+for extension configuration.
+
+Do not use page `localStorage` for extension settings.
+
+The implementation MUST assume `storage.local` is not encrypted.
+
+Do not store:
+
+- passwords;
+- arbitrary secrets;
+- private authentication tokens;
+
+unless a later requirement explicitly adds such functionality and the security model is revised.
+
+The initial local-Ollama design SHOULD require no secret credentials.
+
+---
+
+## 17. Content Security Policy
+
+Keep Firefox's extension CSP as restrictive as practical.
+
+Do not weaken CSP merely to make a library or framework work.
+
+Do not enable:
+
+- remote script execution;
+- `unsafe-eval`;
+- arbitrary inline executable JavaScript.
+
+JavaScript SHOULD be stored in local `.js` files where applicable.
+
+HTML event attributes such as the following SHOULD NOT be used:
+
+```html
+<button onclick="...">
+```
+
+Prefer JavaScript event listeners:
+
+```js
+button.addEventListener("click", handler);
+```
+
+---
+
+## 18. Remote Resource Ban
+
+At runtime, the extension MUST NOT load executable or styling resources from the Internet.
+
+Prohibited runtime resources include:
+
+- JavaScript;
+- CSS;
+- web fonts;
+- icon libraries;
+- UI frameworks;
+- remotely hosted HTML fragments.
+
+The only intended network communication is application data communication with the configured Ollama service.
+
+A future feature that adds any other remote service requires explicit review and an update to this file.
+
+---
+
+## 19. Build and Packaging
+
+The project SHOULD be directly loadable as a Firefox temporary extension without a build step.
+
+Expected development workflow:
+
+```text
+edit source files
+ ->
+about:debugging
+ ->
+This Firefox
+ ->
+Load Temporary Add-on
+ ->
+select manifest.json
+```
+
+A build system MUST NOT be introduced unless an explicit requirement justifies it.
+
+Packaging SHOULD consist of the project files required by the WebExtension package, excluding tests and development-only files where appropriate.
+
+---
+
+## 20. Testing Security Requirements
+
+Security-sensitive behavior MUST be tested.
+
+Minimum cases:
+
+| Test | Expected Result |
+|---|---|
+| Selected text contains `<script>` | Displayed as text, never executed. |
+| LLM returns HTML tags | Displayed as text. |
+| LLM returns `<img onerror=...>` | Displayed as text. |
+| Selected text contains prompt-injection language | Treated only as translation input. |
+| Oversized selected text | Rejected safely. |
+| Invalid numeric option | Rejected or replaced with safe default. |
+| Invalid context preset | Rejected. |
+| Unknown message type | Ignored/rejected. |
+| Rapid repeated translation requests | Previous request is cancelled. |
+| Ollama unavailable | Safe error UI, no exception leak to page. |
+| Malformed Ollama stream chunk | Parser fails safely without executing content. |
+| Page has hostile CSS | Translation UI remains usable where practical. |
+| Page script inspects DOM | No privileged extension object is exposed. |
+
+---
+
+## 21. Logging
+
+Do not log full selected text or full translation results by default.
+
+Development logging SHOULD avoid unnecessary disclosure of page content.
+
+Do not log secrets if credential support is ever added.
+
+Error logs SHOULD contain technical diagnostics without unnecessarily reproducing user-selected text.
+
+---
+
+## 22. Error Handling
+
+Errors MUST fail closed rather than enabling broader privileges or unsafe fallback behavior.
+
+Examples:
+
+- If Ollama host validation fails, do not attempt arbitrary network access.
+- If JSON streaming parsing fails, stop or recover safely.
+- If a setting cannot be validated, use a documented safe default or reject the operation.
+- If content-script messaging fails, do not fall back to page-script execution.
+
+---
+
+## 23. Source Review Policy
+
+Before adding any new external code, dependency, browser API, or permission, the implementation agent MUST answer:
+
+1. Is this required by `Specifications.md`?
+2. Can the same requirement be implemented with a browser/WebExtensions standard API?
+3. Does this introduce a package-manager dependency?
+4. Does this introduce a runtime network dependency?
+5. Does this require a new Firefox permission?
+6. Is the API current and supported by Firefox?
+7. Does it expand the trust boundary?
+8. Can the implementation remain simpler without it?
+
+If the feature can reasonably be implemented without the new dependency or privilege, prefer the dependency-free / lower-privilege implementation.
+
+---
+
+## 24. Explicitly Prohibited Design Changes
+
+Without project-owner approval, the implementation agent MUST NOT:
+
+- add npm dependencies;
+- introduce Node.js tooling;
+- add a JavaScript framework;
+- add a CSS framework;
+- load assets from a CDN;
+- load Google Fonts or other remote fonts;
+- add `ollama-js`;
+- replace direct Ollama REST calls with a third-party client;
+- request unrelated Firefox permissions;
+- introduce Manifest V2 compatibility code;
+- introduce Chromium-only service-worker assumptions into Firefox code;
+- render LLM output using HTML;
+- execute page or LLM content;
+- expose privileged extension functions to page JavaScript;
+- silently add telemetry or analytics;
+- send selected text anywhere other than the explicitly configured Ollama endpoint.
+
+---
+
+## 25. Privacy Requirements
+
+Selected text can contain private or sensitive page content.
+
+Therefore:
+
+- selected text MUST only be sent to the configured Ollama endpoint;
+- the extension MUST NOT send telemetry;
+- the extension MUST NOT send analytics;
+- the extension MUST NOT contact external logging services;
+- the extension MUST NOT automatically fall back to a cloud LLM;
+- connection failures MUST NOT cause data to be sent to another provider;
+- the UI SHOULD make the configured Ollama host visible to the user.
+
+If cloud Ollama support is added later, it must be an explicit user configuration and requires a privacy/security design update.
+
+---
+
+## 26. Implementation Review Checklist
+
+Before declaring implementation complete, verify all of the following.
+
+### Dependencies
+
+- [ ] No `node_modules`.
+- [ ] No npm/yarn/pnpm/bun dependency.
+- [ ] No required Node.js build step.
+- [ ] No third-party JS runtime dependency.
+- [ ] No third-party CSS framework.
+- [ ] No remote fonts.
+- [ ] No CDN resources.
+- [ ] No `ollama-js`.
+
+### Firefox
+
+- [ ] Manifest V3.
+- [ ] Firefox-supported background implementation.
+- [ ] No deprecated WebExtensions API used when a supported current alternative exists.
+- [ ] Permissions are minimal.
+- [ ] No unnecessary `tabs`, `scripting`, `webRequest`, `cookies`, or `nativeMessaging` permission.
+- [ ] Firefox behavior manually verified in `about:debugging`.
+
+### DOM / Page Boundary
+
+- [ ] Page content treated as untrusted.
+- [ ] LLM output treated as untrusted.
+- [ ] `textContent` or equivalent safe APIs used.
+- [ ] No untrusted `innerHTML`.
+- [ ] No `eval()` / `new Function()`.
+- [ ] No page-script privilege bridge.
+- [ ] Shadow DOM does not contain unsafe HTML insertion.
+
+### Messaging
+
+- [ ] Message types are allow-listed.
+- [ ] Payload types are validated.
+- [ ] Selection length limit exists.
+- [ ] Obsolete translation requests are cancelled.
+- [ ] Unknown messages are rejected or ignored safely.
+
+### Network
+
+- [ ] Only background communicates with Ollama.
+- [ ] Ollama host is validated.
+- [ ] No silent fallback endpoint.
+- [ ] Streaming parser handles malformed input safely.
+- [ ] No telemetry or analytics endpoint.
+
+### Settings
+
+- [ ] Numeric values validated.
+- [ ] Seed integer validated.
+- [ ] Context length restricted to supported UI presets.
+- [ ] Temperature validated.
+- [ ] Stored invalid values are handled safely.
+
+### Testing
+
+- [ ] Script/HTML injection strings tested.
+- [ ] Prompt-injection-like selected text tested.
+- [ ] Oversized selection tested.
+- [ ] Ollama offline case tested.
+- [ ] Request cancellation tested.
+- [ ] Malformed streaming data tested.
+- [ ] Settings validation tested.
+
+---
+
+## 27. Definition of Done
+
+Security work is complete only when:
+
+1. all implemented features comply with this document;
+2. the extension runs without Node.js/npm;
+3. all runtime resources are local except Ollama API traffic;
+4. no untrusted page or LLM content is interpreted as executable markup/code;
+5. Firefox permissions and APIs have been reviewed for necessity and current support;
+6. security test cases pass;
+7. deviations from this policy are explicitly documented and approved.