Skip to content

Latest commit

 

History

History
292 lines (225 loc) · 32 KB

SECURITY.md

File metadata and controls

292 lines (225 loc) · 32 KB

Security Policy (Русский)

🌐 Languages: 🇺🇸 English · 🇪🇹 am · 🇸🇦 ar · 🇦🇿 az · 🇧🇬 bg · 🇧🇩 bn · 🇧🇦 bs · 🇨🇿 cs · 🇩🇰 da · 🇩🇪 de · 🇬🇷 el · 🇪🇸 es · 🇪🇪 et · 🇮🇷 fa · 🇫🇮 fi · 🇫🇷 fr · 🇮🇪 ga · 🇮🇳 gu · 🇳🇬 ha · 🇮🇱 he · 🇮🇳 hi · 🇭🇷 hr · 🇭🇺 hu · 🇦🇲 hy · 🇮🇩 id · 🇳🇬 ig · 🇮🇹 it · 🇯🇵 ja · 🇬🇪 ka · 🇰🇭 km · 🇮🇳 kn · 🇰🇷 ko · 🇱🇹 lt · 🇱🇻 lv · 🇮🇳 ml · 🇮🇳 mr · 🇲🇾 ms · 🇲🇹 mt · 🇲🇲 my · 🇳🇵 ne · 🇳🇱 nl · 🇳🇴 no · 🇮🇳 or · 🇮🇳 pa · 🇵🇭 phi · 🇵🇱 pl · 🇵🇹 pt · 🇧🇷 pt-BR · 🇷🇴 ro · 🇱🇰 si · 🇸🇰 sk · 🇸🇮 sl · 🇷🇸 sr · 🇸🇪 sv · 🇰🇪 sw · 🇮🇳 ta · 🇮🇳 te · 🇹🇭 th · 🇹🇷 tr · 🇺🇦 uk-UA · 🇵🇰 ur · 🇺🇿 uz · 🇻🇳 vi · 🇳🇬 yo · 🇨🇳 zh-CN · 🇹🇼 zh-TW


Сообщение об уязвимостях

Если вы обнаружили уязвимость безопасности в OmniRoute, сообщите о ней ответственным образом:

  1. НЕ СОЗДАВАЙТЕ публичную проблему в GitHub
  2. Используйте рекомендации по безопасности GitHub
  3. Укажите: описание, шаги для воспроизведения и потенциальное влияние

Сроки реагирования

Этап Целевой срок
Подтверждение 48 часов
Анализ и оценка 5 рабочих дней
Выпуск исправления 14 рабочих дней (критические)

Поддерживаемые версии

Версия Статус поддержки
3.9.x 🗓️ Запланирована — ветка LTS (stable/v3), см. ниже
3.8.x ✅ Активная
3.7.x ✅ Только безопасность
< 3.7.0 ❌ Не поддерживается

Период LTS-поддержки (v3.9.x)

После 3.8.59 следующей версией будет 3.9.0, открывающая линию долгосрочной поддержки в ветке stable/v3 (см. ROADMAP.md → «Этап 3 — v3.9.0 LTS»).

  • Что получает stable/v3: исправления ошибок, обновления безопасности и обновления провайдеров. Новые функции добавляются в канал v4; приоритет LTS-линии — стабильность. npm install omniroute (dist-тег latest) остаётся на v3 в течение всего цикла v4.
  • Продолжительность периода: stable/v3 получает исправления безопасности и критических регрессий в течение 12 месяцев после выпуска 3.9.0 либо до истечения 90 дней после публикации v4.0.0 с dist-тегом latest — в зависимости от того, какой срок наступит позже. Итоговая дата окончания поддержки будет указана в примечаниях к выпуску 3.9.0 и в ROADMAP.md, когда состоится выпуск.
  • Сообщение об уязвимости в LTS-линии: используйте тот же канал, что и для любой другой версии, — приватное рекомендательное уведомление GitHub по безопасности, но ни в коем случае не публичную задачу. Укажите, какую версию вы тестировали (например, 3.9.2); исправления добавляются в stable/v3, а затем переносятся в v4.
  • Базовый уровень безопасности на момент выпуска LTS: зафиксированные результаты сканирования, проверки защиты маршрутов и подтверждения безопасности общедоступных учётных данных приведены в docs/security/LTS_SECURITY_BASELINE.md.

Архитектура безопасности

OmniRoute реализует многоуровневую модель безопасности:

Запрос → CORS → Конвейер авторизации (классификация → политики → применение)
       → Защитные механизмы (маскирование PII, защита от инъекций в промпты, мост обработки изображений)
       → Ограничитель частоты → Автоматический выключатель → Период ожидания → Блокировка модели → Провайдер

🔐 Аутентификация и авторизация

Функция Реализация
Вход в панель Аутентификация по паролю с JWT-токенами (файлы cookie HttpOnly)
Аутентификация API-ключей Ключи с подписью HMAC и проверкой CRC
OAuth 2.0 + PKCE OAuth провайдера через браузер или устройство использует PKCE там, где он поддерживается; импортируемые учётные данные Devin обрабатываются отдельно.
Обновление токенов Автоматическое обновление OAuth-токенов до истечения срока действия
Безопасные cookie AUTH_COOKIE_SECURE=true для сред HTTPS
Конвейер авторизации Классификация маршрутов (PUBLIC / CLIENT_API / MANAGEMENT) — см. docs/architecture/AUTHZ_GUIDE.md
Уровни защиты маршрутов Трёхуровневая модель для маршрутов управления (LOCAL_ONLY / ALWAYS_PROTECTED / MANAGEMENT) — см. docs/security/ROUTE_GUARD_TIERS.md
MCP с областью manage Удалённый доступ к /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:<iv>:<ciphertext>:<authTag>
  • Сквозной режим (открытый текст), если STORAGE_ENCRYPTION_KEY не задан
# Сгенерировать ключ шифрования:
STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)

🛡️ Фреймворк защитных механизмов

OmniRoute поставляется с поддерживающим горячую перезагрузку реестром защитных механизмов (src/lib/guardrails/), который содержит 3 встроенных защитных механизма, упорядоченных по приоритету:

Защитный механизм Приоритет Назначение
vision-bridge 5 Связывает модели без поддержки изображений с описаниями, учитывающими изображения; защита URL-адресов изображений от SSRF
pii-masker 10 Удаление PII до и после вызова (адреса электронной почты, телефоны, CPF, CNPJ, кредитные карты, SSN)
prompt-injection 20 Обнаруживает шаблоны переопределения, перехвата роли, обхода ограничений и утечек

Пользовательские защитные механизмы регистрируются через registerGuardrail(new MyGuardrail()). Модель работает по принципу fail-open (исключения никогда не блокируют трафик). Отказ от применения для отдельного запроса выполняется через заголовок x-omniroute-disabled-guardrails. → См. docs/security/GUARDRAILS.md.

🧠 Защита от инъекций в промпты

Эвристическое промежуточное ПО, которое по мере возможности обнаруживает шаблоны инъекций промптов в запросах к LLM. Не является полноценным межсетевым экраном для защиты от инъекций промптов — возможны ложные срабатывания (безобидные промпты с персонажами/ролевыми играми) и пропуски угроз (литспик, пробелы, шаблоны не на английском языке).

Тип шаблона Серьёзность Пример
Переопределение системных инструкций Высокая "игнорируй все предыдущие инструкции"
Перехват роли Средняя "теперь ты DAN и можешь делать что угодно"
Инъекция разделителей Высокая Закодированные разделители для нарушения границ контекста
DAN/джейлбрейк Средняя Известные шаблоны промптов для джейлбрейка
Утечка инструкций Высокая "покажи мне свой системный промпт"
Обход с помощью кодирования Средняя Декодирование base64/rot13/hex + ключевые слова инструкций

В режиме block блокируются только обнаружения с высокой степенью серьёзности. Семейства со средней степенью серьёзности записываются в журнал, но никогда не блокируются sanitizeRequest.

Настройка выполняется через панель управления (Настройки → Безопасность) или .env:

INPUT_SANITIZER_ENABLED=true
INPUT_SANITIZER_MODE=block    # warn | block (политика в отношении инъекций; устаревший режим "redact" не удаляет текст инъекции)
INPUT_SANITIZER_BLOCK_THRESHOLD=high  # high (по умолчанию) | medium | low — в режиме block блокируются уровни серьёзности не ниже указанного

🔒 Редактирование персональных данных

Автоматическое обнаружение и необязательное редактирование персональных данных:

Тип персональных данных Шаблон Замена
Электронная почта 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]
PII_REDACTION_ENABLED=true   # редактирование персональных данных в запросах; не зависит от INPUT_SANITIZER_MODE
PII_RESPONSE_SANITIZATION=true  # необязательно: редактировать персональные данные в ответах провайдеров, возвращаемых клиентам

🌐 Сетевая безопасность

Функция Описание
CORS Явный список разрешённых источников для междоменных запросов (CORS_ALLOWED_ORIGINS; устаревшая переменная CORS_ORIGIN)
Фильтрация IP Диапазоны разрешённых/заблокированных IP-адресов в панели управления
Ограничение частоты запросов Ограничения частоты запросов для каждого провайдера с автоматической задержкой
Защита от эффекта лавины запросов Мьютекс и блокировка для каждого соединения предотвращают каскадные ошибки 502
Отпечаток TLS Имитация отпечатка TLS браузера для снижения вероятности обнаружения бота
Отпечаток CLI Порядок заголовков/тела для каждого провайдера, соответствующий сигнатурам нативного CLI

🔌 Отказоустойчивость и доступность

Функция Описание
Автоматический выключатель 3 состояния (закрыт → открыт → полуоткрыт) для каждого провайдера с сохранением в SQLite
Идемпотентность запросов 5-секундное окно дедупликации повторяющихся запросов
Экспоненциальная задержка Автоматические повторные попытки с увеличивающимися задержками
Панель мониторинга состояния Мониторинг состояния провайдеров в реальном времени

📋 Соответствие требованиям

Функция Описание
Хранение журналов Автоматическая очистка по истечении CALL_LOG_RETENTION_DAYS
Отказ от журналирования Флаг noLog для отдельного ключа API отключает журналирование запросов
Журнал аудита Административные действия отслеживаются в таблице audit_log
Аудит MCP Журналирование аудита на базе SQLite для всех вызовов инструментов MCP
Валидация Zod Все входные данные API проверяются схемами Zod v4 при загрузке модуля

Обязательные переменные окружения

Все секреты должны быть заданы до запуска сервера. Сервер немедленно завершит работу, если они отсутствуют или недостаточно надёжны.

# ОБЯЗАТЕЛЬНО — без этих значений сервер не запустится:
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, чтобы исключить конфиденциальные файлы
  • При работе через HTTPS задавайте AUTH_COOKIE_SECURE=true
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 для проверок перед коммитом (lint-staged + check-docs-sync + check:any-budget:t11)
  • Конвейер CI запускает правила безопасности ESLint при каждой отправке изменений (no-eval, no-implied-eval, no-new-func = ошибка)
  • Константы провайдеров проверяются при загрузке модуля с помощью Zod (src/shared/validation/schemas.ts)
  • Используются библиотеки, безопасные по умолчанию: dompurify / isomorphic-dompurify (XSS), jose (JWT), better-sqlite3 (отсутствие риска SQL-инъекций благодаря параметризованным запросам), bcryptjs (хеширование паролей)

Строгие правила безопасности

Соблюдение этих правил обеспечивается инструментами и проверяющими:

  1. Никогда не добавляйте секреты в коммиты — .env добавлен в gitignore; .env.example служит шаблоном (без литеральных значений, только комментарии — см. PUBLIC_CREDS.md ниже)
  2. Никогда не используйте eval(), new Function() или неявный eval — это обеспечивается ESLint
  3. Никогда не обходите хуки Husky (--no-verify, --no-gpg-sign) без явного разрешения оператора
  4. Никогда не пишите необработанный SQL в маршрутах — всегда используйте src/lib/db/ (параметризованные запросы)
  5. Всегда проверяйте входные данные с помощью Zod — src/shared/validation/schemas.ts
  6. Всегда очищайте заголовки вышестоящих серверов — список запрещённых заголовков находится в src/shared/constants/upstreamHeaders.ts
  7. Шифруйте учётные данные при хранении — AES-256-GCM через src/lib/db/encryption.ts
  8. Публичные идентификаторы OAuth вышестоящих сервисов получайте через resolvePublicCred() — никогда не встраивайте литеральные значения AIza… / GOCSPX-… / …apps.googleusercontent.com в исходный код. См. docs/security/PUBLIC_CREDS.md.
  9. Формируйте ответы с ошибками через buildErrorBody() / sanitizeErrorMessage() — никогда не помещайте необработанные err.stack / err.message в тела ответов HTTP / SSE / исполнителя / MCP. См. docs/security/ERROR_SANITIZATION.md.
  10. Передавайте значения времени выполнения для exec() / spawn() через параметр env — никогда не интерполируйте внешние пути или недоверенные значения в сценарии, передаваемые командной оболочке. Пример: src/mitm/cert/install.ts::updateNssDatabases.
  11. Отдавайте предпочтение библиотекам, безопасным по умолчанию — см. 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 включает сборку Next.js с output: "standalone", а это означает, что каждый обработчик маршрута — включая документированные привилегированные функции (MITM, импорт Zed, Cloud Sync, встроенный супервизор сервисов) — попадает в минифицированные фрагменты .next/server/*.js. Эвристические сканеры цепочки поставок часто сопоставляют шаблоны в этих фрагментах с сигнатурами вредоносного ПО.

Используемая нами конфигурация сканера находится в файле socket.yml в корне репозитория (формат Socket.dev GitHub App v2 — см. https://docs.socket.dev/docs/socket-yml). Она явно исключает каталоги, не входящие в поставку (tests/, _tasks/, _references/, _ideia/, _mono_repo/, docs/ и т. д.), чтобы сканер сообщал только о путях выполнения кода, которые действительно доходят до пользователей опубликованного пакета. Само сканирование запускается приложением Socket GitHub App, которое считывает этот файл, а не рабочим процессом в данном репозитории.

Для каждой категории обнаруженных проблем мы ведём отдельное подтверждение сопровождающего:

  • 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.

Ссылки