summaryrefslogtreecommitdiff
path: root/doc/Security.md
blob: 956f16993b1d82aa66b4537a2308ab136edddc6c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
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.