# 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:` or `http://127.0.0.1:`. 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()` | | Selection context menu translation | `menus` (selection context only) | | 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 menus ``` 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:` or `http://127.0.0.1:` 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. The `menus` permission is used exclusively for the selection-context translation entry point (context menu "選択したテキストを翻訳"). It MUST NOT be used for any other purpose (no page action items, no tab items, no bookmark items, no launcher items). 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 / PDF Viewer selection | | selected text (content script or menus.selectionText) v Content Script / menu-controller (background) | | 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. ### 7.4 Firefox PDF Viewer and Context Menu Input Firefox's built-in PDF Viewer is privileged browser UI: - The extension MUST NOT attempt to inject content scripts into it. - The extension MUST NOT access its internal DOM, PDF.js internal objects, `wrappedJSObject`, `cloneInto`, `exportFunction`, or any Firefox-internal URI/API to work around the injection restriction. - PDF translation is provided exclusively through the public `menus` API. `menus.OnClickData.selectionText` is UNTRUSTED input: - it MUST pass the same validation pipeline as content-script selections (string type check, trim, empty rejection, maximum length, control character handling) before being sent to Ollama; - it MUST NOT be treated as trusted control input or rendered as HTML; - the translation result MUST be rendered in the Action Popup with `textContent`-style plain-text rendering only. --- ## 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