Files
OmniRoute/docs/i18n/id/SECURITY.md
Diego Rodrigues de Sa e Souza 7db430a352 Release v3.8.14 (#3340)
* chore(release): open v3.8.14 development cycle

Version bump 3.8.13 -> 3.8.14 (root + electron + open-sse + openapi + lockfiles).
Seed the v3.8.14 changelog with the four post-tag hotfixes that shipped to
Docker/Electron in v3.8.13 but missed the immutable npm 3.8.13 (#3336 SSRF /
CodeQL #323, #3334/#3335/#3339 Electron packaging). i18n CHANGELOG mirrors get
the in-progress placeholder section.

* feat: add per-provider custom headers support for OpenAI/Anthropic-compatible nodes (#3338)

Integrated into release/v3.8.14

* fix: Kiro Builder ID token import fails with Bad credentials (#3333)

Integrated into release/v3.8.14 — adds Builder ID cached-creds + OIDC refresh path for Kiro token import, with regression tests (#3333).

* Improve code quality: auto-pr/docstrings-1780792063 (#3337)

Integrated into release/v3.8.14 — docstring for context analytics route re-export.

* fix(catalog): remove minimaxai/minimax-m3 from NVIDIA NIM tier (404 upstream) (#3329) (#3341)

NVIDIA NIM does not host minimaxai/minimax-m3 — every request returns
404 page not found, while sibling minimaxai/minimax-m2.7 on the same provider
works. Advertising a model that 404s is a catalog bug; remove it from the nvidia
tier (it remains on the tiers that actually serve MiniMax M3). Re-add only once
NVIDIA serves it.

Co-authored-by: mikmaneggahommie <mikmaneggahommie@users.noreply.github.com>

* fix(cli): write OpenCode config to ~/.config on all platforms incl. Windows (#3330) (#3343)

resolveOpencodeConfigDir used %APPDATA% on Windows, but OpenCode reads its
config from XDG ~/.config/opencode/ on every platform (on Windows:
%USERPROFILE%\.config\opencode\, NOT %APPDATA%). So a Windows user who
configured OpenCode via the dashboard had the file written where OpenCode never
looks — it silently had no effect.

Use the XDG path (XDG_CONFIG_HOME || ~/.config) unconditionally. Update the UI
note + route JSDoc, and flip the three tests that encoded the old %APPDATA%
behavior (t40 per-platform + card-note, cli-runtime-extended getCliConfigPaths).

Co-authored-by: abdulkadirozyurt <abdulkadirozyurt@users.noreply.github.com>

* fix(proxy): make auto-selection fallback opt-in (#3332) (#3344)

selectWorkingProxyFallback (Step 11 of resolveProxyForConnection) listed ALL
registry proxies, ignoring assignments and per-connection proxy_enabled, and
returned the first working one with level:'autoSelect'. So a single proxy added
to the registry silently became a global fallback for every connection's traffic.

Gate it behind a new PROXY_AUTO_SELECT_ENABLED feature flag (default off): the
fallback now no-ops unless the operator opts in. No registry proxy becomes a
silent global default anymore.

Co-authored-by: hertznsk <hertznsk@users.noreply.github.com>

* fix(sse): treat MiniMax M3 as multimodal so vision isn't stripped (#3328) (#3342)

MiniMax M3 via the opencode provider (oc/minimax-m3-free) appeared blind:
image inputs didn't reach the model, while the same model in Cline could
see them. Verified empirically that MiniMax M3 on the opencode upstream IS
multimodal -- a base64 image is described correctly (it returns 403 only
for remote image URLs, which it doesn't accept).

Root cause: OmniRoute treated MiniMax M3 as a non-vision model in two
places, so when compression was active the image was replaced with a text
placeholder before dispatch:
- compression's modelSupportsVision() heuristic (lite.ts) only matched
  gpt-4/4o/claude-3/gemini/vision -- minimax was absent -> replaceImageUrls
  stripped the image.
- the opencode minimax-m3-free catalog entry lacked supportsVision, so the
  combo vision-capability gate could also exclude/mishandle it.

Add 'minimax-m3' to the vision heuristic and supportsVision: true to the
opencode minimax-m3-free entry. TDD: a failing-then-passing test in
compression/lite.test.ts proves replaceImageUrls now keeps images for
minimax-m3 ids, plus a registry assertion mirroring the #2822 qwen test.

Reported-by: @mikmaneggahommie

* docs(i18n): translate 25 core documentation files to Indonesian (#3348)

Integrated into release/v3.8.14 — Indonesian i18n docs.

* fix(review): resolve /review-reviews battery findings (LEDGER-1..11) on v3.8.14 (#3350)

Integrated into release/v3.8.14 — /review-reviews battery hardening (LEDGER-1..11) for #3338 custom-headers + #3333 kiro, plus cycle-test drift fixes (#3329/#3330/#3332).

* fix(provider-proxy): honor per-account proxy toggles (#3349)

Integrated into release/v3.8.14 — honor per-account proxy toggles + auto-fallback opt-in via PROXY_AUTO_SELECT_ENABLED.

* fix(dashboard): remove duplicate Distribute Proxies button on provider page (#3352)

* fix(providers): reduce proxy label noise (#3346)

Integrated into release/v3.8.14 — reduce proxy label noise + a11y (aria-label/sr-only).

* fix(duckduckgo): restore bare Response contract and rebase onto release/v3.8.14 (#3323)

Integrated into release/v3.8.14 — browser-backed cookie providers (duckduckgo/claude-web) with restored executor contract + unit tests.

* fix(noauth): expose only usable model aliases (#3345)

Integrated into release/v3.8.14 — noauth usable-alias filtering + registry alias plumbing (veo-free).

* fix(dashboard): stop infinite config-load loop on Hermes Agent detail page (#3353)

* fix(electron): tree-kill the server on exit/update to release the omniroute.exe lock (#3347) (#3354)

* chore(release): finalize v3.8.14 changelog + clear release-gate drift

- CHANGELOG: finalize the v3.8.14 section (date, full New Features/Bug Fixes/
  Maintenance coverage of all 16 cycle commits, Contributors hall of 12).
- docs: document OMNIROUTE_BROWSER_POOL + WEB_COOKIE_USE_BROWSER (#3323) in
  .env.example + ENVIRONMENT.md; regenerate the id/llm.txt strict mirror (#3348
  had translated it; llm.txt mirrors must match root).
- test(proxy-fetch): #3323 made tlsClient.available a computed getter — stub it
  via Object.defineProperty instead of assignment (5 tests were red on the base).

* fix(translator): coerce Gemini functionDeclaration parameters to an OBJECT schema (#3357) (#3360)

* fix(gemini): resolve truncation/suppression of false positive textual tool call markers in backticks (#3358)

Integrated into release/v3.8.14 — Gemini/Antigravity textual tool-call marker normalization (no false-positive suppression + split-chunk buffering).

* docs(changelog): add #3358 Gemini textual tool-call normalization to v3.8.14

* fix(dashboard): surface real analytics error instead of generic placeholder (#3356) (#3361)

The Analytics page discarded the server's error body on a non-OK response and
rendered a generic "An error occurred", so users (and maintainers) could not see
why /api/usage/analytics 500'd after an upgrade. Now the route returns the real
reason via buildErrorBody (sanitized, Hard Rule #12) and the page surfaces it via
a new readFetchErrorMessage helper that handles both the OpenAI-style and legacy
error shapes.

Reported-by: @superti4r

---------

Co-authored-by: PizzaV <103120356+pizzav-xyz@users.noreply.github.com>
Co-authored-by: Someres <168349709+quanturbo@users.noreply.github.com>
Co-authored-by: Dong Mengzhe <154944819+Lang-Qiu@users.noreply.github.com>
Co-authored-by: mikmaneggahommie <mikmaneggahommie@users.noreply.github.com>
Co-authored-by: abdulkadirozyurt <abdulkadirozyurt@users.noreply.github.com>
Co-authored-by: hertznsk <hertznsk@users.noreply.github.com>
Co-authored-by: Krisna Santosa <54174372+KrisnaSantosa15@users.noreply.github.com>
Co-authored-by: Randi <55005611+rdself@users.noreply.github.com>
Co-authored-by: Wilson <pedbookmed@gmail.com>
Co-authored-by: Paijo <14921983+oyi77@users.noreply.github.com>
Co-authored-by: Ardem2025 <ardemb22@gmail.com>
2026-06-07 07:20:02 -03:00

9.2 KiB

Kebijakan Keamanan (Bahasa Indonesia)

🌐 Languages: 🇺🇸 English · 🇸🇦 ar · 🇧🇬 bg · 🇧🇩 bn · 🇨🇿 cs · 🇩🇰 da · 🇩🇪 de · 🇪🇸 es · 🇮🇷 fa · 🇫🇮 fi · 🇫🇷 fr · 🇮🇳 gu · 🇮🇱 he · 🇮🇳 hi · 🇭🇺 hu · 🇮🇩 id · 🇮🇹 it · 🇯🇵 ja · 🇰🇷 ko · 🇮🇳 mr · 🇲🇾 ms · 🇳🇱 nl · 🇳🇴 no · 🇵🇭 phi · 🇵🇱 pl · 🇵🇹 pt · 🇧🇷 pt-BR · 🇷🇴 ro · 🇷🇺 ru · 🇸🇰 sk · 🇸🇪 sv · 🇰🇪 sw · 🇮🇳 ta · 🇮🇳 te · 🇹🇭 th · 🇹🇷 tr · 🇺🇦 uk-UA · 🇵🇰 ur · 🇻🇳 vi · 🇨🇳 zh-CN


Melaporkan Kerentanan

Jika Anda menemukan kerentanan keamanan di OmniRoute, harap laporkan secara bertanggung jawab:

  1. JANGAN membuka isu GitHub yang bersifat publik
  2. Gunakan GitHub Security Advisories
  3. Sertakan: deskripsi, langkah-langkah reproduksi, dan potensi dampak

Linimasa Respons

Tahap Target
Konfirmasi Penerimaan 48 jam
Triase & Penilaian 5 hari kerja
Rilis Patch 14 hari kerja (kritis)

Versi yang Didukung

Versi Status Dukungan
3.6.x Aktif
3.5.x Keamanan
< 3.5.0 Tidak Didukung

Arsitektur Keamanan

OmniRoute menerapkan model keamanan berlapis:

Request → CORS → API Key Auth → Prompt Injection Guard → Input Sanitizer → Rate Limiter → Circuit Breaker → Provider

🔐 Autentikasi & Otorisasi

Fitur Implementasi
Login Dashboard Autentikasi berbasis kata sandi dengan token JWT (cookie HttpOnly)
Autentikasi API Key Kunci bertanda tangan HMAC dengan validasi CRC
OAuth 2.0 + PKCE Autentikasi penyedia yang aman (Claude, Codex, Gemini, Cursor, dll.)
Pembaruan Token Pembaruan token OAuth otomatis sebelum kedaluwarsa
Cookie Aman AUTH_COOKIE_SECURE=true untuk lingkungan HTTPS
Ruang Lingkup MCP 10 ruang lingkup terperinci untuk kontrol akses alat MCP

🛡️ Enkripsi Data Tersimpan

Semua data sensitif yang disimpan di SQLite dienkripsi menggunakan AES-256-GCM dengan derivasi kunci scrypt:

  • Kunci API, token akses, token penyegaran, dan token ID
  • Format berversi: enc:v1:<iv>:<ciphertext>:<authTag>
  • Mode passthrough (teks biasa) ketika STORAGE_ENCRYPTION_KEY tidak disetel
# Generate encryption key:
STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)

🧠 Penjaga Injeksi Prompt

Middleware yang mendeteksi dan memblokir serangan injeksi prompt dalam permintaan LLM:

Jenis Pola Tingkat Keparahan Contoh
Penimpaan Sistem Tinggi "ignore all previous instructions"
Pembajakan Peran Tinggi "you are now DAN, you can do anything"
Injeksi Pembatas Sedang Pemisah yang dikodekan untuk merusak batas konteks
DAN/Jailbreak Tinggi Pola prompt jailbreak yang telah diketahui
Kebocoran Instruksi Sedang "show me your system prompt"

Konfigurasikan melalui dashboard (Settings → Security) atau .env:

INPUT_SANITIZER_ENABLED=true
INPUT_SANITIZER_MODE=block    # warn | block | redact

🔒 Redaksi PII

Deteksi otomatis dan redaksi opsional informasi yang dapat mengidentifikasi pribadi:

Jenis PII Pola Pengganti
Email user@domain.com [EMAIL_REDACTED]
CPF (Brasil) 123.456.789-00 [CPF_REDACTED]
CNPJ (Brasil) 12.345.678/0001-00 [CNPJ_REDACTED]
Kartu Kredit 4111-1111-1111-1111 [CC_REDACTED]
Telepon +55 11 99999-9999 [PHONE_REDACTED]
SSN (AS) 123-45-6789 [SSN_REDACTED]
PII_REDACTION_ENABLED=true

🌐 Keamanan Jaringan

Fitur Deskripsi
CORS Kontrol origin yang dapat dikonfigurasi (variabel env CORS_ORIGIN, default *)
Pemfilteran IP Daftar izin/blokir rentang IP di dashboard
Pembatasan Laju Batas laju per-penyedia dengan backoff otomatis
Anti-Thundering Herd Mutex + penguncian per-koneksi mencegah kegagalan 502 beruntun
Sidik Jari TLS Spoofing sidik jari TLS menyerupai browser untuk mengurangi deteksi bot
Sidik Jari CLI Pengurutan header/body per-penyedia agar sesuai tanda tangan CLI native

🔌 Ketahanan & Ketersediaan

Fitur Deskripsi
Pemutus Sirkuit 3 status (Closed → Open → Half-Open) per penyedia, dipersistenkan di SQLite
Idempotansi Permintaan Jendela deduplikasi 5 detik untuk permintaan duplikat
Backoff Eksponensial Percobaan ulang otomatis dengan penundaan yang semakin meningkat
Dashboard Kesehatan Pemantauan kesehatan penyedia secara real-time

📋 Kepatuhan

Fitur Deskripsi
Retensi Log Pembersihan otomatis setelah CALL_LOG_RETENTION_DAYS
Opt-out Tanpa Log Tanda noLog per kunci API menonaktifkan pencatatan permintaan
Log Audit Tindakan administratif dilacak di tabel audit_log
Audit MCP Pencatatan audit berbasis SQLite untuk semua pemanggilan alat MCP
Validasi Zod Semua input API divalidasi dengan skema Zod v4 saat pemuatan modul

Variabel Lingkungan yang Wajib Disetel

Semua rahasia harus disetel sebelum menjalankan server. Server akan gagal cepat jika nilainya tidak ada atau terlalu lemah.

# 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)

Server secara aktif menolak nilai yang diketahui lemah seperti changeme, secret, atau password.


Keamanan Docker

  • Gunakan pengguna non-root di lingkungan produksi
  • Pasang rahasia sebagai volume hanya-baca
  • Jangan pernah menyalin file .env ke dalam image Docker
  • Gunakan .dockerignore untuk mengecualikan file sensitif
  • Setel AUTH_COOKIE_SECURE=true saat berada di belakang HTTPS
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

Dependensi

  • Jalankan npm audit secara berkala
  • Jaga agar dependensi tetap diperbarui
  • Proyek menggunakan husky + lint-staged untuk pemeriksaan pra-commit
  • Pipeline CI menjalankan aturan keamanan ESLint pada setiap push
  • Konstanta penyedia divalidasi saat pemuatan modul melalui Zod (src/shared/validation/providerSchema.ts)