# Security Policy (עברית) 🌐 **Languages:** 🇺🇸 [English](../../../SECURITY.md) · 🇪🇹 [am](../am/SECURITY.md) · 🇸🇦 [ar](../ar/SECURITY.md) · 🇦🇿 [az](../az/SECURITY.md) · 🇧🇬 [bg](../bg/SECURITY.md) · 🇧🇩 [bn](../bn/SECURITY.md) · 🇧🇦 [bs](../bs/SECURITY.md) · 🇨🇿 [cs](../cs/SECURITY.md) · 🇩🇰 [da](../da/SECURITY.md) · 🇩🇪 [de](../de/SECURITY.md) · 🇬🇷 [el](../el/SECURITY.md) · 🇪🇸 [es](../es/SECURITY.md) · 🇪🇪 [et](../et/SECURITY.md) · 🇮🇷 [fa](../fa/SECURITY.md) · 🇫🇮 [fi](../fi/SECURITY.md) · 🇫🇷 [fr](../fr/SECURITY.md) · 🇮🇪 [ga](../ga/SECURITY.md) · 🇮🇳 [gu](../gu/SECURITY.md) · 🇳🇬 [ha](../ha/SECURITY.md) · 🇮🇳 [hi](../hi/SECURITY.md) · 🇭🇷 [hr](../hr/SECURITY.md) · 🇭🇺 [hu](../hu/SECURITY.md) · 🇦🇲 [hy](../hy/SECURITY.md) · 🇮🇩 [id](../id/SECURITY.md) · 🇳🇬 [ig](../ig/SECURITY.md) · 🇮🇹 [it](../it/SECURITY.md) · 🇯🇵 [ja](../ja/SECURITY.md) · 🇬🇪 [ka](../ka/SECURITY.md) · 🇰🇭 [km](../km/SECURITY.md) · 🇮🇳 [kn](../kn/SECURITY.md) · 🇰🇷 [ko](../ko/SECURITY.md) · 🇱🇹 [lt](../lt/SECURITY.md) · 🇱🇻 [lv](../lv/SECURITY.md) · 🇮🇳 [ml](../ml/SECURITY.md) · 🇮🇳 [mr](../mr/SECURITY.md) · 🇲🇾 [ms](../ms/SECURITY.md) · 🇲🇹 [mt](../mt/SECURITY.md) · 🇲🇲 [my](../my/SECURITY.md) · 🇳🇵 [ne](../ne/SECURITY.md) · 🇳🇱 [nl](../nl/SECURITY.md) · 🇳🇴 [no](../no/SECURITY.md) · 🇮🇳 [or](../or/SECURITY.md) · 🇮🇳 [pa](../pa/SECURITY.md) · 🇵🇭 [phi](../phi/SECURITY.md) · 🇵🇱 [pl](../pl/SECURITY.md) · 🇵🇹 [pt](../pt/SECURITY.md) · 🇧🇷 [pt-BR](../pt-BR/SECURITY.md) · 🇷🇴 [ro](../ro/SECURITY.md) · 🇷🇺 [ru](../ru/SECURITY.md) · 🇱🇰 [si](../si/SECURITY.md) · 🇸🇰 [sk](../sk/SECURITY.md) · 🇸🇮 [sl](../sl/SECURITY.md) · 🇷🇸 [sr](../sr/SECURITY.md) · 🇸🇪 [sv](../sv/SECURITY.md) · 🇰🇪 [sw](../sw/SECURITY.md) · 🇮🇳 [ta](../ta/SECURITY.md) · 🇮🇳 [te](../te/SECURITY.md) · 🇹🇭 [th](../th/SECURITY.md) · 🇹🇷 [tr](../tr/SECURITY.md) · 🇺🇦 [uk-UA](../uk-UA/SECURITY.md) · 🇵🇰 [ur](../ur/SECURITY.md) · 🇺🇿 [uz](../uz/SECURITY.md) · 🇻🇳 [vi](../vi/SECURITY.md) · 🇳🇬 [yo](../yo/SECURITY.md) · 🇨🇳 [zh-CN](../zh-CN/SECURITY.md) · 🇹🇼 [zh-TW](../zh-TW/SECURITY.md) --- ## דיווח על פגיעויות אם גיליתם פגיעות אבטחה ב-OmniRoute, אנא דווחו עליה באופן אחראי: 1. **אין** לפתוח דיווח ציבורי ב-GitHub 2. השתמשו ב-[התראות האבטחה של GitHub](https://github.com/diegosouzapw/OmniRoute/security/advisories/new) 3. כללו: תיאור, שלבים לשחזור והשפעה אפשרית ## לוח זמנים לתגובה | שלב | יעד | | ----------- | --------------------------- | | אישור קבלה | 48 שעות | | מיון והערכה | 5 ימי עסקים | | פרסום תיקון | 14 ימי עסקים (לבעיה קריטית) | ## גרסאות נתמכות | גרסה | סטטוס תמיכה | | ------- | ----------- | | 3.8.x | ✅ פעילה | | 3.7.x | ✅ אבטחה | | < 3.7.0 | ❌ לא נתמכת | --- ## ארכיטקטורת אבטחה OmniRoute מממש מודל אבטחה רב-שכבתי: ``` בקשה → CORS → צינור Authz (סיווג → מדיניות → אכיפה) → מנגנוני הגנה (מיסוך PII, הזרקת הנחיות, גשר ראייה) → מגביל קצב → מפסק זרם → תקופת צינון → חסימת מודל → ספק ``` ### 🔐 אימות והרשאה | תכונה | מימוש | | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **כניסה ללוח הבקרה** | אימות מבוסס סיסמה באמצעות אסימוני JWT (קובצי Cookie מסוג HttpOnly) | | **אימות באמצעות מפתח API** | מפתחות חתומים באמצעות HMAC עם אימות CRC | | **OAuth 2.0 + PKCE** | OAuth ייעודי לספק בדפדפן/מכשיר משתמש ב-PKCE כאשר הוא נתמך; פרטי גישה של Devin המיועדים לייבוא בלבד מטופלים בנפרד. | | **רענון אסימונים** | רענון אוטומטי של אסימוני OAuth לפני פקיעת תוקפם | | **קובצי Cookie מאובטחים** | `AUTH_COOKIE_SECURE=true` עבור סביבות HTTPS | | **צינור Authz** | סיווג נתיבים (PUBLIC / CLIENT_API / MANAGEMENT) — ראו `docs/architecture/AUTHZ_GUIDE.md` | | **רמות הגנת נתיבים** | מודל בן 3 רמות עבור נתיבי ניהול (LOCAL_ONLY / ALWAYS_PROTECTED / MANAGEMENT) — ראו `docs/security/ROUTE_GUARD_TIERS.md` | | **MCP בהיקף ניהול** | גישה מרוחקת אל `/api/mcp/*` מוגנת באמצעות מפתחות API עם היקף `manage`; הנתיב `/api/cli-tools/runtime/*` נותר מוגבל בקפדנות ל-loopback. ראו ROUTE_GUARD_TIERS | | **היקפי MCP** | 32 היקפים מפורטים (read:health, write:combos, execute:completions וכו׳) — ראו `docs/frameworks/MCP-SERVER.md` | ### 🛡️ הצפנה במנוחה כל הנתונים הרגישים המאוחסנים ב-SQLite מוצפנים באמצעות **AES-256-GCM**, עם גזירת מפתח באמצעות scrypt: - מפתחות API, אסימוני גישה, אסימוני רענון ואסימוני ID - פורמט הכולל גרסה: `enc:v1:::` - מצב העברה ללא שינוי (טקסט גלוי) כאשר `STORAGE_ENCRYPTION_KEY` אינו מוגדר ```bash # יצירת מפתח הצפנה: STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32) ``` ### 🛡️ מסגרת מנגנוני ההגנה OmniRoute כולל **רישום מנגנוני הגנה** (`src/lib/guardrails/`) הניתן לטעינה מחדש בזמן אמת, עם 3 מנגנוני הגנה מובנים המסודרים לפי עדיפות: | מנגנון הגנה | עדיפות | מטרה | | ------------------ | ------ | ---------------------------------------------------------------------------------------------- | | `vision-bridge` | 5 | מגשר בין מודלים ללא יכולות ראייה לבין תיאורים מודעי-תמונה; הגנת SSRF עבור כתובות URL של תמונות | | `pii-masker` | 10 | השחרת PII לפני ואחרי קריאה (כתובות דוא״ל, טלפון, CPF, CNPJ, כרטיסי אשראי, SSN) | | `prompt-injection` | 20 | מזהה דפוסי עקיפה, חטיפת תפקיד, פריצה ודליפה | מנגנוני הגנה מותאמים אישית נרשמים באמצעות `registerGuardrail(new MyGuardrail())`. המודל פועל בגישת fail-open (חריגות לעולם אינן חוסמות תעבורה). ניתן לבטל עבור בקשה מסוימת באמצעות הכותרת `x-omniroute-disabled-guardrails`. ← ראו [`docs/security/GUARDRAILS.md`](docs/security/GUARDRAILS.md). ### 🧠 הגנה מפני הזרקת הנחיות תווכה היוריסטית במאמץ מיטבי, המזהה דפוסים של הזרקת הנחיות בבקשות LLM. **אין זו חומת אש מלאה מפני הזרקת הנחיות** — היא עלולה להפיק תוצאות חיוביות שגויות (הנחיות תמימות של דמויות/משחקי תפקידים) ותוצאות שליליות שגויות (leetspeak, ריווח ודפוסים שאינם באנגלית). | סוג דפוס | חומרה | דוגמה | | --------------------- | ------- | -------------------------------------------- | | עקיפת מערכת | גבוהה | "התעלם מכל ההנחיות הקודמות" | | חטיפת תפקיד | בינונית | "כעת אתה DAN, אתה יכול לעשות הכול" | | הזרקת תוחמים | גבוהה | מפרידים מקודדים לשבירת גבולות ההקשר | | DAN/פריצה | בינונית | דפוסים מוכרים של הנחיות פריצה | | דליפת הנחיות | גבוהה | "הצג לי את הנחיית המערכת שלך" | | התחמקות באמצעות קידוד | בינונית | פענוח base64/rot13/hex ומילות מפתח של הנחיות | רק זיהויים ברמת חומרה **גבוהה** נחסמים במצב `block`. משפחות ברמת חומרה בינונית נרשמות ביומן, אך לעולם אינן נחסמות על ידי `sanitizeRequest`. ניתן להגדיר זאת באמצעות לוח הבקרה (הגדרות ← אבטחה) או `.env`: ```env INPUT_SANITIZER_ENABLED=true INPUT_SANITIZER_MODE=block # warn | block (מדיניות הזרקה; האפשרות הישנה "redact" אינה מסירה טקסט של הזרקה) INPUT_SANITIZER_BLOCK_THRESHOLD=high # high (ברירת מחדל) | medium | low — רמות חומרה השוות לסף זה או גבוהות ממנו נחסמות במצב block ``` ### 🔒 השחרת PII זיהוי אוטומטי והשחרה אופציונלית של מידע המאפשר זיהוי אישי: | סוג מידע אישי מזהה | תבנית | החלפה | | ------------------ | --------------------- | ------------------ | | דוא״ל | `user@domain.com` | `[EMAIL_REDACTED]` | | CPF (ברזיל) | `123.456.789-00` | `[CPF_REDACTED]` | | CNPJ (ברזיל) | `12.345.678/0001-00` | `[CNPJ_REDACTED]` | | כרטיס אשראי | `4111-1111-1111-1111` | `[CC_REDACTED]` | | טלפון | `+55 11 99999-9999` | `[PHONE_REDACTED]` | | SSN (ארה״ב) | `123-45-6789` | `[SSN_REDACTED]` | ```env PII_REDACTION_ENABLED=true # בקשת שכתוב מידע אישי מזהה; בלתי תלוי ב-INPUT_SANITIZER_MODE PII_RESPONSE_SANITIZATION=true # אופציונלי: השחרת מידע אישי מזהה בתגובות ספקים המוחזרות ללקוחות ``` ### 🌐 אבטחת רשת | תכונה | תיאור | | --------------------- | -------------------------------------------------------------------------------------------------- | | **CORS** | רשימת מקורות מורשים מפורשת לבקשות חוצות-מקור (`CORS_ALLOWED_ORIGINS`; האפשרות הישנה `CORS_ORIGIN`) | | **סינון IP** | טווחי כתובות IP מותרים/חסומים בלוח הבקרה | | **הגבלת קצב** | מגבלות קצב לכל ספק עם השהיה אוטומטית | | **מניעת עומס מתפרץ** | Mutex + נעילה לכל חיבור מונעים שגיאות 502 מתגלגלות | | **טביעת אצבע של TLS** | זיוף טביעת אצבע של TLS בדומה לדפדפן, כדי להפחית זיהוי בוטים | | **טביעת אצבע של CLI** | סדר כותרות/גוף ייחודי לכל ספק, התואם לחתימות CLI מקוריות | ### 🔌 חוסן וזמינות | תכונה | תיאור | | ---------------------- | ------------------------------------------------------------- | | **מפסק זרם** | 3 מצבים (סגור → פתוח → פתוח למחצה) לכל ספק, עם שמירה ב-SQLite | | **אידמפוטנטיות בקשות** | חלון מניעת כפילויות של 5 שניות עבור בקשות כפולות | | **השהיה מעריכית** | ניסיון חוזר אוטומטי עם זמני השהיה הולכים וגדלים | | **לוח בקרת תקינות** | ניטור תקינות ספקים בזמן אמת | ### 📋 תאימות | תכונה | תיאור | | ------------------------ | ----------------------------------------------------------- | | **שמירת יומנים** | ניקוי אוטומטי לאחר `CALL_LOG_RETENTION_DAYS` | | **ויתור על רישום ביומן** | הדגל `noLog` לכל מפתח API משבית את רישום הבקשות ביומן | | **יומן ביקורת** | פעולות ניהוליות מתועדות בטבלה `audit_log` | | **ביקורת MCP** | רישום ביקורת מבוסס SQLite עבור כל הקריאות לכלי MCP | | **אימות Zod** | כל קלטי ה-API מאומתים באמצעות סכמות Zod v4 בעת טעינת המודול | --- ## משתני סביבה נדרשים יש להגדיר את כל הסודות לפני הפעלת השרת. השרת **ייכשל מיד** אם הם חסרים או חלשים. ```bash # חובה — השרת לא יופעל בלעדיהם: JWT_SECRET=$(openssl rand -base64 48) # לפחות 32 תווים API_KEY_SECRET=$(openssl rand -hex 32) # לפחות 16 תווים # מומלץ — מאפשר הצפנת נתונים במנוחה: STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32) ``` השרת דוחה באופן פעיל ערכים חלשים מוכרים כגון `changeme`, `secret` או `password`. --- ## אבטחת Docker - השתמשו במשתמש שאינו root בסביבת הייצור - עגנו סודות כאמצעי אחסון לקריאה בלבד - לעולם אל תעתיקו קובצי `.env` לתמונות Docker - השתמשו ב-`.dockerignore` כדי להחריג קבצים רגישים - הגדירו `AUTH_COOKIE_SECURE=true` כאשר המערכת פועלת מאחורי 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 ``` --- ## תלויות - הריצו את `npm audit` באופן קבוע (`npm run audit:deps` מכסה את היישום הראשי ואת electron) - הקפידו לעדכן את התלויות - הפרויקט משתמש ב-`husky` וב-`lint-staged` לבדיקות לפני commit‏ (lint-staged + check-docs-sync + check:any-budget:t11) - תהליך ה-CI מריץ כללי אבטחה של ESLint בכל push‏ (`no-eval`, `no-implied-eval`, `no-new-func` = שגיאה) - קבועי ספקים מאומתים בעת טעינת המודול באמצעות Zod‏ (`src/shared/validation/schemas.ts`) - נעשה שימוש בספריות מאובטחות כברירת מחדל: `dompurify` / `isomorphic-dompurify`‏ (XSS),‏ `jose`‏ (JWT),‏ `better-sqlite3`‏ (ללא סיכון ל-SQLi הודות לשאילתות עם פרמטרים), `bcryptjs`‏ (גיבוב סיסמאות) ## כללי אבטחה מחייבים כלים וסוקרים אוכפים את הכללים הבאים: 1. **לעולם אל תבצעו commit של סודות** — הקובץ `.env` מוחרג באמצעות gitignore; הקובץ `.env.example` הוא התבנית (ללא ערכים מילוליים, הערות בלבד — ראו PUBLIC_CREDS.md להלן) 2. **לעולם אל תשתמשו ב-`eval()`, ב-`new Function()` או ב-eval משתמע** — ESLint אוכף זאת 3. **לעולם אל תעקפו hooks של Husky**‏ (`--no-verify`, `--no-gpg-sign`) ללא אישור מפורש מהמפעיל 4. **לעולם אל תכתבו SQL גולמי בנתיבים** — עברו תמיד דרך `src/lib/db/` (עם פרמטרים) 5. **אמתו תמיד קלטים באמצעות Zod** — `src/shared/validation/schemas.ts` 6. **טהרו תמיד כותרות upstream** — רשימת החסימה נמצאת ב-`src/shared/constants/upstreamHeaders.ts` 7. **הצפינו פרטי גישה במנוחה** — AES-256-GCM באמצעות `src/lib/db/encryption.ts` 8. **מזהי OAuth ציבוריים של upstream באמצעות `resolvePublicCred()`** — לעולם אל תטמיעו ערכים מילוליים מסוג `AIza…` / `GOCSPX-…` / `…apps.googleusercontent.com` בקוד המקור. ראו [`docs/security/PUBLIC_CREDS.md`](docs/security/PUBLIC_CREDS.md). 9. **תגובות שגיאה באמצעות `buildErrorBody()` / `sanitizeErrorMessage()`** — לעולם אל תכללו `err.stack` / `err.message` גולמיים בגופי תגובה של HTTP / SSE / executor / MCP. ראו [`docs/security/ERROR_SANITIZATION.md`](docs/security/ERROR_SANITIZATION.md). 10. **ערכי זמן ריצה של `exec()` / `spawn()` באמצעות האפשרות `env`** — לעולם אל תשלבו נתיבים חיצוניים או ערכים שאינם מהימנים באמצעות אינטרפולציה של מחרוזות בסקריפטים המועברים ל-shell. לעיון: `src/mitm/cert/install.ts::updateNssDatabases`. 11. **העדיפו ספריות מאובטחות כברירת מחדל** — ראו [tldrsec/awesome-secure-defaults](https://github.com/tldrsec/awesome-secure-defaults)‏ (Helmet.js, DOMPurify, ssrf-req-filter, safe-regex, Google Tink). השתמשו בהן לפני שתפתחו פתרון משלכם. ## ממצאי סורקי שרשרת האספקה (Socket.dev / Snyk / כלים דומים) > **הערת היקף:** הקובץ `socket.yml` בשורש המאגר מגדיר רק את `projectIgnorePaths` עבור הסריקה שלאחר הפרסום בצד הרישום של Socket.dev על ארטיפקט ה-npm שפורסם — הוא אינו שער מיזוג נאכף ב-CI/PR. שום תהליך עבודה תחת `.github/workflows`, שום סקריפט של `package.json` ושום יעד של `Makefile` אינם מפעילים את Socket.dev. ארטיפקט ה-npm המפורסם `omniroute` כולל את תוצר הבנייה `output: "standalone"` של Next.js, כלומר כל מטפל בנתיב — כולל יכולות מתועדות הדורשות הרשאות מיוחדות (MITM, ייבוא Zed, סנכרון ענן ומפקח שירות מוטמע) — מגיע למקטעים הממוזערים תחת `.next/server/*.js`. סורקי שרשרת אספקה היוריסטיים מתאימים לעיתים קרובות את המקטעים האלה לתבניות של חתימות נוזקה. תצורת הסורק שבה אנו משתמשים נמצאת ב-[`socket.yml`](socket.yml) בשורש המאגר (פורמט v2 של אפליקציית GitHub של Socket.dev — ראו ). היא מחריגה במפורש ספריות שאינן מופצות (`tests/`, `_tasks/`, `_references/`, `_ideia/`, `_mono_repo/`, `docs/` וכו׳), כך שהסורק מדווח רק על נתיבי קוד שמגיעים בפועל למשתמשים במוצר שפורסם — הסריקה עצמה מופעלת כאשר אפליקציית GitHub של Socket קוראת את הקובץ הזה, ולא באמצעות תהליך עבודה במאגר זה. עבור כל קטגוריית ממצאים אנו מתחזקים הצהרת אימות של המתחזקים לכל ממצא: - **[`docs/security/SOCKET_DEV_FINDINGS.md`](docs/security/SOCKET_DEV_FINDINGS.md)** — מיפוי לכל ממצא: קובץ מקור ↔ מקטע שסומן ↔ התנהגות ↔ מיתון שהוחל ב-v3.8.6. - בלוקי `SECURITY-AUDITOR-NOTE:` בתוך קוד המקור, בכל פונקציה שסומנה, מפנים חזרה לאותו מסמך. למשתמשים שתהליך העיבוד שלהם אינו מאפשר הקלה בהתראה: בצעו בנייה באמצעות `OMNIROUTE_BUILD_PROFILE=minimal npm run build`. פעולה זו מחליפה את ארבעת המודולים הרגישים במימושי דמה שמחזירים בזמן ריצה HTTP 503 מסוג `feature-disabled`, כך שנתיבי הקוד הדורשים הרשאות מיוחדות נעדרים פיזית מהחבילה. ראו [`docs/security/SOCKET_DEV_FINDINGS.md`](docs/security/SOCKET_DEV_FINDINGS.md) לקבלת מתכון הפרסום. ## מקורות - [`docs/architecture/AUTHZ_GUIDE.md`](docs/architecture/AUTHZ_GUIDE.md) — תהליך ההרשאה - [`docs/security/GUARDRAILS.md`](docs/security/GUARDRAILS.md) — מסגרת מנגנוני ההגנה - [`docs/security/COMPLIANCE.md`](docs/security/COMPLIANCE.md) — יומן ביקורת ושימור - [`docs/security/PUBLIC_CREDS.md`](docs/security/PUBLIC_CREDS.md) — תבנית **חובה** לאישורי גישה ציבוריים לשירותים במעלה הזרם - [`docs/security/ERROR_SANITIZATION.md`](docs/security/ERROR_SANITIZATION.md) — תבנית **חובה** לתגובות שגיאה - [`docs/security/SOCKET_DEV_FINDINGS.md`](docs/security/SOCKET_DEV_FINDINGS.md) — הצהרת אימות של המתחזקים לממצאי סורקי שרשרת האספקה - [`docs/architecture/RESILIENCE_GUIDE.md`](docs/architecture/RESILIENCE_GUIDE.md) — מפסק מעגל + תקופת צינון + נעילה - [`docs/security/STEALTH_GUIDE.md`](docs/security/STEALTH_GUIDE.md) — טביעת אצבע של TLS (הודעה משפטית/אתית) - [`CLAUDE.md`](CLAUDE.md) — כללים מחייבים לסוכני AI - [tldrsec/awesome-secure-defaults](https://github.com/tldrsec/awesome-secure-defaults) — ספריות שנבחרו בקפידה ומאובטחות כברירת מחדל