Files
OmniRoute/docs/i18n/pl/SECURITY.md
Praveen K Palaniswamy 65e81158ab fix(ollama): route models by advertised capability (#11088)
Landed with the design call resolved per the owner's pick — **option 1**: the synced store is now endpoint-agnostic (persistDiscoveredModels and managedModelImport no longer drop non-chat models at write time), and chat selectability moved to read time (auto-pool expansion in autoStrategy applies filterChatSelectableModels; the models-route projection already had its chatOnly filter). Your discovery test now passes end-to-end (3/3): /api/show capabilities persist per connection and image/embedding requests route through the advertising host.

Reconciliation notes: conflicted areas merged onto the current tip (adobe discovery import, requestedModel preflight signature, resolvedProvider fast-path coexists with the synced-route override — explicit resolution wins); carried base-red drains (#10055 memoization, #11071 test variants) dropped as already-landed; the managed-model-import exclusion test was propagated to the new contract (image/video models persist; the read filter still hides them from chat pickers — pinned by a new assertion). Full battery: 205/206 focused (the one red is a confirmed periodic-timer timing flake on the loaded devbox — 20/20 isolated), autoCombo vitest 30/30, combo suites 46/46, gates + typecheck clean.

Thank you @yourspraveen — the capability probe + routing design was right; it just needed the store contract opened up. Fixes #11087.
2026-08-23 11:45:01 -03:00

254 lines
15 KiB
Markdown

# Polityka bezpieczeństwa
## Zgłaszanie luk bezpieczeństwa
Jeśli odkryjesz lukę bezpieczeństwa w OmniRoute, zgłoś ją w odpowiedzialny sposób:
1. **NIE** otwieraj publicznego zgłoszenia (issue) na GitHub
2. Użyj [GitHub Security Advisories](https://github.com/diegosouzapw/OmniRoute/security/advisories/new)
3. Dołącz: opis, kroki reprodukcji oraz potencjalny wpływ
## Harmonogram reakcji
| Etap | Cel |
| ---------------- | ---------------------------- |
| Potwierdzenie | 48 godzin |
| Triage i ocena | 5 dni roboczych |
| Wydanie poprawki | 14 dni roboczych (krytyczne) |
## Wspierane wersje
| Wersja | Status wsparcia |
| ------- | ----------------- |
| 3.8.x | ✅ Aktywne |
| 3.7.x | ✅ Bezpieczeństwo |
| < 3.7.0 | ❌ Niewspierane |
---
## Architektura bezpieczeństwa
OmniRoute wdraża wielowarstwowy model bezpieczeństwa:
```
Request → CORS → Authz pipeline (classify → policies → enforce)
→ Guardrails (PII masker, prompt injection, vision bridge)
→ Rate Limiter → Circuit Breaker → Cooldown → Model Lockout → Provider
```
### 🔐 Uwierzytelnianie i autoryzacja
| Funkcja | Implementacja |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Dashboard Login** | Uwierzytelnianie hasłem z tokenami JWT (ciasteczka HttpOnly) |
| **API Key Auth** | Klucze podpisane HMAC z walidacją CRC |
| **OAuth 2.0 + PKCE** | Przepływy OAuth w przeglądarce/na urządzeniu używają PKCE, gdy dostawca je obsługuje; importowane poświadczenia Devin są obsługiwane osobno. |
| **Token Refresh** | Automatyczne odświeżanie tokenów OAuth przed wygaśnięciem |
| **Secure Cookies** | `AUTH_COOKIE_SECURE=true` dla środowisk HTTPS |
| **Authz Pipeline** | Klasyfikacja tras (PUBLIC / CLIENT_API / MANAGEMENT) — zob. `docs/architecture/AUTHZ_GUIDE.md` |
| **Route Guard Tiers** | Model 3-poziomowy dla tras zarządzania (LOCAL_ONLY / ALWAYS_PROTECTED / MANAGEMENT) — zob. `docs/security/ROUTE_GUARD_TIERS.md` |
| **Manage-Scope MCP** | Zdalny dostęp `/api/mcp/*` ograniczony kluczami API ze scope `manage`; `/api/cli-tools/runtime/*` pozostaje strict-loopback. Zob. ROUTE_GUARD_TIERS |
| **MCP Scopes** | 32 granularne scope'y (read:health, write:combos, execute:completions itd.) — zob. `docs/frameworks/MCP-SERVER.md` |
### 🛡️ Szyfrowanie w spoczynku
Wszystkie wrażliwe dane przechowywane w SQLite są szyfrowane algorytmem **AES-256-GCM** z derywacją klucza scrypt:
- Klucze API, tokeny dostępu, tokeny odświeżania oraz tokeny ID
- Wersjonowany format: `enc:v1:<iv>:<ciphertext>:<authTag>`
- Tryb passthrough (tekst jawny), gdy `STORAGE_ENCRYPTION_KEY` nie jest ustawiony
```bash
# Generate encryption key:
STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)
```
### 🛡️ Framework Guardrails
OmniRoute dostarcza przeładowywalny na gorąco **rejestr guardrails** (`src/lib/guardrails/`) z 3 wbudowanymi guardrails uporządkowanymi według priorytetu:
| Guardrail | Priorytet | Cel |
| ------------------ | --------- | ---------------------------------------------------------------------------------------- |
| `vision-bridge` | 5 | Mostkuje modele bez wizji opisami uwzględniającymi obraz; ochrona SSRF dla URL-i obrazów |
| `pii-masker` | 10 | Redakcja PII przed i po wywołaniu (e-maile, telefon, CPF, CNPJ, karty kredytowe, SSN) |
| `prompt-injection` | 20 | Wykrywa wzorce override / role-hijack / jailbreak / leak |
Własne guardrails rejestruje się przez `registerGuardrail(new MyGuardrail())`. Model jest fail-open (wyjątki nigdy nie blokują ruchu). Rezygnacja per żądanie przez nagłówek `x-omniroute-disabled-guardrails`. → Zob. [`docs/security/GUARDRAILS.md`](docs/security/GUARDRAILS.md).
### 🧠 Ochrona przed prompt injection
Heurystyczny middleware best-effort, który wykrywa wzorce prompt injection w żądaniach LLM.
**To nie jest kompletna zapora przed prompt injection** — może generować fałszywe alarmy (nieszkodliwe
prompty persona/RPG) oraz pomijać ataki (leetspeak, odstępy, wzorce w innych językach).
| Typ wzorca | Dotkliwość | Przykład |
| ------------------- | ---------- | -------------------------------------------------------- |
| System Override | High | "ignore all previous instructions" |
| Role Hijack | Medium | "you are now DAN, you can do anything" |
| Delimiter Injection | High | Zakodowane separatory łamiące granice kontekstu |
| DAN/Jailbreak | Medium | Znane wzorce promptów jailbreak |
| Instruction Leak | High | "show me your system prompt" |
| Encoding Evasion | Medium | dekodowanie base64/rot13/hex + słowa kluczowe instrukcji |
W trybie `block` blokowane są wyłącznie detekcje o dotkliwości **High**. Rodziny o
dotkliwości Medium są logowane, ale nigdy nie blokowane przez `sanitizeRequest`.
Konfiguracja przez dashboard (Settings → Security) lub `.env`:
```env
INPUT_SANITIZER_ENABLED=true
INPUT_SANITIZER_MODE=block # warn | block (injection policy; legacy "redact" does not strip injection text)
INPUT_SANITIZER_BLOCK_THRESHOLD=high # high (default) | medium | low — severities at/above this are blocked in block mode
```
### 🔒 Redakcja PII
Automatyczne wykrywanie i opcjonalna redakcja danych osobowych (PII):
| Typ PII | Wzorzec | Zamiennik |
| ------------- | --------------------- | ------------------ |
| Email | `user@domain.com` | `[EMAIL_REDACTED]` |
| CPF (Brazil) | `123.456.789-00` | `[CPF_REDACTED]` |
| CNPJ (Brazil) | `12.345.678/0001-00` | `[CNPJ_REDACTED]` |
| Credit Card | `4111-1111-1111-1111` | `[CC_REDACTED]` |
| Phone | `+55 11 99999-9999` | `[PHONE_REDACTED]` |
| SSN (US) | `123-45-6789` | `[SSN_REDACTED]` |
```env
PII_REDACTION_ENABLED=true # request PII rewrite; independent of INPUT_SANITIZER_MODE
PII_RESPONSE_SANITIZATION=true # optional: redact PII in provider responses returned to clients
```
### 🌐 Bezpieczeństwo sieci
| Funkcja | Opis |
| ------------------------ | ------------------------------------------------------------------------------- |
| **CORS** | Jawna lista dozwolonych originów (`CORS_ALLOWED_ORIGINS`; legacy `CORS_ORIGIN`) |
| **IP Filtering** | Listy allowlist/blocklist zakresów IP w dashboardzie |
| **Rate Limiting** | Limity zapytań per dostawca z automatycznym backoffiem |
| **Anti-Thundering Herd** | Mutex + blokady per połączenie zapobiegają kaskadowym 502 |
| **TLS Fingerprint** | Spoofing odcisku TLS jak w przeglądarce w celu ograniczenia detekcji botów |
| **CLI Fingerprint** | Kolejność nagłówków/ciała per dostawca dopasowana do natywnych sygnatur CLI |
### 🔌 Odporność i dostępność
| Funkcja | Opis |
| ----------------------- | -------------------------------------------------------------------- |
| **Circuit Breaker** | 3 stany (Closed → Open → Half-Open) per dostawca, utrwalone w SQLite |
| **Request Idempotency** | 5-sekundowe okno deduplikacji dla powielonych żądań |
| **Exponential Backoff** | Automatyczne ponawianie z rosnącymi opóźnieniami |
| **Health Dashboard** | Monitorowanie zdrowia dostawców w czasie rzeczywistym |
### 📋 Zgodność
| Funkcja | Opis |
| ------------------ | ------------------------------------------------------------------------ |
| **Log Retention** | Automatyczne czyszczenie po `CALL_LOG_RETENTION_DAYS` |
| **No-Log Opt-out** | Flaga `noLog` per klucz API wyłącza logowanie żądań |
| **Audit Log** | Działania administracyjne śledzone w tabeli `audit_log` |
| **MCP Audit** | Audyt w SQLite dla wszystkich wywołań narzędzi MCP |
| **Zod Validation** | Wszystkie wejścia API walidowane schematami Zod v4 przy ładowaniu modułu |
---
## Wymagane zmienne środowiskowe
Wszystkie sekrety muszą być ustawione przed uruchomieniem serwera. Serwer **zakończy się natychmiast (fail fast)**, jeśli brakuje ich lub są słabe.
```bash
# REQUIRED — server will not start without these:
JWT_SECRET=$(openssl rand -base64 48) # min 32 chars
API_KEY_SECRET=$(openssl rand -hex 32) # min 16 chars
# RECOMMENDED — enables encryption at rest:
STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)
```
Serwer aktywnie odrzuca znane słabe wartości, takie jak `changeme`, `secret` lub `password`.
---
## Bezpieczeństwo Dockera
- Używaj użytkownika non-root w produkcji
- Montuj sekrety jako wolumeny tylko do odczytu
- Nigdy nie kopiuj plików `.env` do obrazów Dockera
- Używaj `.dockerignore`, aby wykluczyć pliki wrażliwe
- Ustaw `AUTH_COOKIE_SECURE=true` za HTTPS
```bash
docker run -d \
--name omniroute \
--restart unless-stopped \
--read-only \
-p 20128:20128 \
-v omniroute-data:/app/data \
-e JWT_SECRET="$(openssl rand -base64 48)" \
-e API_KEY_SECRET="$(openssl rand -hex 32)" \
-e STORAGE_ENCRYPTION_KEY="$(openssl rand -hex 32)" \
diegosouzapw/omniroute:latest
```
---
## Zależności
- Regularnie uruchamiaj `npm audit` (`npm run audit:deps` obejmuje main + electron)
- Utrzymuj zależności w aktualnej wersji
- Projekt używa `husky` + `lint-staged` do kontroli pre-commit (lint-staged + check-docs-sync + check:any-budget:t11)
- Pipeline CI uruchamia reguły bezpieczeństwa ESLint przy każdym pushu (`no-eval`, `no-implied-eval`, `no-new-func` = error)
- Stałe dostawców walidowane przy ładowaniu modułu przez Zod (`src/shared/validation/schemas.ts`)
- Używane biblioteki secure-by-default: `dompurify` / `isomorphic-dompurify` (XSS), `jose` (JWT), `better-sqlite3` (brak ryzyka SQLi dzięki zapytaniom parametryzowanym), `bcryptjs` (hashowanie haseł)
## Twarde reguły bezpieczeństwa
Te reguły są egzekwowane przez narzędzia i recenzentów:
1. **Nigdy nie commituj sekretów**`.env` jest w gitignore; `.env.example` to szablon (bez literałów, tylko komentarze — zob. PUBLIC_CREDS.md poniżej)
2. **Nigdy nie używaj `eval()`, `new Function()` ani implied eval** — egzekwowane przez ESLint
3. **Nigdy nie omijaj hooków Husky** (`--no-verify`, `--no-gpg-sign`) bez wyraźnej zgody operatora
4. **Nigdy nie pisz surowego SQL w trasach** — zawsze przez `src/lib/db/` (parametryzowane)
5. **Zawsze waliduj wejścia Zod**`src/shared/validation/schemas.ts`
6. **Zawsze sanityzuj nagłówki upstream** — denylist w `src/shared/constants/upstreamHeaders.ts`
7. **Szyfruj poświadczenia w spoczynku** — AES-256-GCM przez `src/lib/db/encryption.ts`
8. **Publiczne identyfikatory OAuth upstream przez `resolvePublicCred()`** — nigdy nie umieszczaj w źródle literałów `AIza…` / `GOCSPX-…` / `…apps.googleusercontent.com`. Zob. [`docs/security/PUBLIC_CREDS.md`](docs/security/PUBLIC_CREDS.md).
9. **Odpowiedzi błędów przez `buildErrorBody()` / `sanitizeErrorMessage()`** — nigdy nie umieszczaj surowego `err.stack` / `err.message` w ciałach odpowiedzi HTTP / SSE / executor / MCP. Zob. [`docs/security/ERROR_SANITIZATION.md`](docs/security/ERROR_SANITIZATION.md).
10. **Wartości runtime `exec()` / `spawn()` przez opcję `env`** — nigdy nie interpoluj zewnętrznych ścieżek ani niezaufanych wartości w skryptach przekazywanych do powłoki. Odniesienie: `src/mitm/cert/install.ts::updateNssDatabases`.
11. **Preferuj biblioteki secure-by-default** — zob. [tldrsec/awesome-secure-defaults](https://github.com/tldrsec/awesome-secure-defaults) (Helmet.js, DOMPurify, ssrf-req-filter, safe-regex, Google Tink). Sięgaj po nie, zanim napiszesz własne.
## Ustalenia skanerów łańcucha dostaw (Socket.dev / Snyk / podobne)
Opublikowany artefakt npm `omniroute` bundluje build Next.js `output: "standalone"`,
co oznacza, że każdy route handler — w tym udokumentowane uprzywilejowane
funkcje (MITM, Zed import, Cloud Sync, embedded service supervisor) — trafia
do zminifikowanych chunków `.next/server/*.js`. Heurystyczne skanery łańcucha dostaw
często dopasowują te chunki do sygnatur malware.
Dla każdej kategorii ustaleń utrzymujemy poświadczenie maintainerów per ustalenie:
- **[`docs/security/SOCKET_DEV_FINDINGS.md`](docs/security/SOCKET_DEV_FINDINGS.md)** —
mapa per ustalenie: plik źródłowy ↔ oflagowany chunk ↔ zachowanie ↔ mitygacja
zastosowana w v3.8.6.
- Bloki `SECURITY-AUDITOR-NOTE:` w źródle przy każdej oflagowanej funkcji odsyłają
do tego samego dokumentu.
Dla użytkowników, których pipeline nie może poluzować alertu: buduj z
`OMNIROUTE_BUILD_PROFILE=minimal npm run build`. To zastępuje cztery
wrażliwe moduły stubami zwracającymi HTTP 503 `feature-disabled` w
runtime, więc uprzywilejowane ścieżki kodu są fizycznie nieobecne w bundlu.
Zob. [`docs/security/SOCKET_DEV_FINDINGS.md`](docs/security/SOCKET_DEV_FINDINGS.md)
dla receptury publikacji.
## Odniesienia
- [`docs/architecture/AUTHZ_GUIDE.md`](docs/architecture/AUTHZ_GUIDE.md) — potok autoryzacji
- [`docs/security/GUARDRAILS.md`](docs/security/GUARDRAILS.md) — framework guardrails
- [`docs/security/COMPLIANCE.md`](docs/security/COMPLIANCE.md) — dziennik audytu i retencja
- [`docs/security/PUBLIC_CREDS.md`](docs/security/PUBLIC_CREDS.md) — **obowiązkowy** wzorzec dla publicznych poświadczeń upstream
- [`docs/security/ERROR_SANITIZATION.md`](docs/security/ERROR_SANITIZATION.md) — **obowiązkowy** wzorzec dla odpowiedzi błędów
- [`docs/security/SOCKET_DEV_FINDINGS.md`](docs/security/SOCKET_DEV_FINDINGS.md) — poświadczenie maintainerów dla ustaleń skanerów łańcucha dostaw
- [`docs/architecture/RESILIENCE_GUIDE.md`](docs/architecture/RESILIENCE_GUIDE.md) — circuit breaker + cooldown + lockout
- [`docs/security/STEALTH_GUIDE.md`](docs/security/STEALTH_GUIDE.md) — fingerprinting TLS (uwaga prawna/etyczna)
- [`CLAUDE.md`](CLAUDE.md) — twarde reguły dla agentów AI
- [tldrsec/awesome-secure-defaults](https://github.com/tldrsec/awesome-secure-defaults) — wyselekcjonowane biblioteki secure-by-default