Socket.dev / supply-chain finding attestation (Русский)
§1 — Установка корневого ЦС для MITM (77484.js)
Заголовок раздела «§1 — Установка корневого ЦС для MITM (77484.js)»Исходные файлы:
src/mitm/cert/install.ts— публичныеinstallCert()/uninstallCert(), платформозависимыеinstallCertWindows/Mac/Linux.src/mitm/systemCommands.ts— общие вспомогательные функцииexecFile/spawn/ PowerShell, используемые путями установки.
Условие запуска: пользователь нажимает «Включить MITM-прокси» на локальной панели управления по адресу
/dashboard/cli-tools/mitm. Маршрут доступен только через loopback-интерфейс — см. строгое правило №17 в
CLAUDE.md и src/server/authz/routeGuard.ts::isLocalOnlyPath(). Утёкший
JWT, раскрытый через туннель, не может активировать этот путь кода.
Выполняемые привилегированные операции (для каждой платформы):
| ОС | Команда(-ы) |
|---|---|
| Windows | certutil -addstore Root <cert> через UAC |
| macOS | sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain <cert> |
| Linux | sudo cp <cert> <distro-trust-dir> + sudo update-ca-certificates (Debian) / sudo update-ca-trust (RHEL/SUSE) |
| Linux+Firefox/Chromium | обновление базы данных NSS для каждого профиля через certutil -d sql:<profile> |
Эти же команды используются в mitmproxy, Charles Proxy, Fiddler и
Caddy. Факт их наличия в OmniRoute задокументирован в
docs/security/STEALTH_GUIDE.md.
Меры по устранению в v3.8.6:
runElevatedPowerShell()больше не использует-EncodedCommand <base64utf16le>. Полезная нагрузка для запуска с повышенными привилегиями записывается в отдельный для каждого вызова временный файл.ps1(режим 0o600, внутри приватного каталогаmkdtempSync) и указывается через-File. Файл удаляется в блокеfinally. Это устраняет классическую сигнатуру повышения привилегий через PowerShell с использованием base64, отмеченную ИИ-классификатором Socket.dev.installCertWindowsсодержит встроенный блокSECURITY-AUDITOR-NOTE:, ссылающийся на этот документ.
Почему мы сохраняем эту функциональность: MITM-прокси — это документированная возможность, описанная в
docs/security/STEALTH_GUIDE.md и docs/frameworks/MITM-PROXY.md. Её удаление
нарушило бы работу набора функций моста агентов.
§2 — Импорт учётных данных Zed (app/api/providers/zed/import/route.js)
Заголовок раздела «§2 — Импорт учётных данных Zed (app/api/providers/zed/import/route.js)»Исходные файлы:
src/app/api/providers/zed/discover/route.ts(добавлен в v3.8.6)src/app/api/providers/zed/import/route.tssrc/lib/zed-oauth/keychain-reader.tssrc/lib/zed-oauth/credentialFingerprint.ts(добавлен в v3.8.6)
Условие запуска: пользователь нажимает «Импортировать из Zed» на странице провайдеров локальной панели управления. Доступ к конечной точке ограничен с помощью requireManagementAuth. Сам редактор Zed записывает API-ключи провайдеров в хранилище ключей ОС под документированными именами служб — см. https://zed.dev/docs/ai/llm-providers.
Поведение v3.8.5 (на которое указал Socket.dev):
POST /import обнаруживал учётные данные и автоматически сохранял их в локальном хранилище SQLite за один запрос. Без подтверждения для каждой учётной записи, без отпечатка — только «найдено N токенов, все импортированы».
Меры по снижению риска в v3.8.6 — двухэтапное подтверждение:
POST /api/providers/zed/discoverвозвращает{ candidates: [{ provider, service, account, fingerprint }] }. Необработанный токен никогда не передаётся. Отпечаток вычисляется какsha256(service|account|token).slice(0,16).- Панель управления отображает список кандидатов, оператор выбирает, какие из них
импортировать, и отправляет
{ confirmedAccounts: [{ service, account, fingerprint }] }вPOST /api/providers/zed/import. - Конечная точка импорта повторно считывает хранилище ключей на сервере и фильтрует по
(service, account, fingerprint). Подделанный или повторно воспроизведённый ответ обнаружения не может заставить конечную точку импорта сохранить посторонний токен — если актуальный токен изменился с момента обнаружения, отпечаток больше не совпадёт, и учётные данные будут пропущены.
Переменная окружения OMNIROUTE_ZED_IMPORT_LEGACY_ONE_STEP=true сохраняет поведение v3.8.5
для операторов, которые ещё не обновили свою автоматизацию. Она будет
удалена в v3.9.
Почему мы сохраняем эту возможность: импорт из Zed — наиболее удобный способ первоначальной настройки для пользователей, которые уже используют Zed и хотят скопировать ключи своих провайдеров в OmniRoute без повторной вставки.
§3 — execFile / spawn / PowerShell с повышенными привилегиями (21843.js)
Заголовок раздела «§3 — execFile / spawn / PowerShell с повышенными привилегиями (21843.js)»Исходные файлы: src/mitm/systemCommands.ts.
Почему отмечено: чанк повторно экспортирует execFileWithPassword,
runElevatedPowerShell и общий вспомогательный модуль quotePowerShell. ИИ-классификатор
Socket.dev расценивает их как универсальный «инструментарий для выполнения команд на хосте и
повышения привилегий». В OmniRoute они используются только в процессе установки
MITM-сертификата (§1), а также функцией execFileWithPassword для выполнения команд через sudo.
Меры по снижению риска в v3.8.6:
- Рефакторинг
runElevatedPowerShell(см. §1). - Встроенный блок
SECURITY-AUDITOR-NOTE:вrunElevatedPowerShellиexecFileWithPasswordдокументирует вызывающие стороны из списка разрешённых и закреплённый список исполняемых файлов. - Вызов
spawn()вexecFileWithPasswordсодержит маркерnosemgrepсо списком разрешённых исполняемых файлов, которые может принимать вспомогательная функция, — путь от пользовательского ввода кfinalCommand/finalArgsотсутствует.
§4 / §6 — Супервизор службы 9router (api/services/9router/{start,restart}/route.js)
Заголовок раздела «§4 / §6 — Супервизор службы 9router (api/services/9router/{start,restart}/route.js)»Исходные файлы:
src/app/api/services/9router/_lib.ts— фабрика супервизора.src/app/api/services/9router/{start,stop,restart,status,install,update,auto-start}/route.ts.src/lib/services/ServiceSupervisor.ts— универсальный запуск процессов / опрос состояния / буфер журналов.
Условие запуска: пользователь нажимает «Установить» / «Запустить» на странице встроенных служб в локальной панели управления.
Уже реализованные меры защиты:
- Все маршруты
/api/services/*имеют статус LOCAL_ONLY согласноsrc/server/authz/routeGuard.ts(жёсткое правило №17). Проверка обращения через loopback-интерфейс выполняется до любой проверки аутентификации — утёкший JWT не позволит получить к ним доступ. - Строка 9router в БД создаётся со значениями
status='not_installed', auto_start=0(см.src/lib/db/migrations/071_services.sql:19). Служба не запускается при первом старте. spawn()вызывается с путём к бинарному файлу, возвращённымresolveSpawnArgs(apiKey, PORT)вsrc/lib/services/installers/ninerouter.ts, где задан фиксированный список разрешённых поддерживаемых бинарных файлов.- Stdout/stderr буферизуются в памяти (ограничение — 5 МБ, см.
_lib.ts) — запись на диск не выполняется, если пользователь не включит журналирование в панели управления.
Меры по снижению риска в v3.8.6: функциональных изменений нет. Минимальный профиль сборки
(OMNIROUTE_BUILD_PROFILE=minimal) заменяет
src/lib/services/installers/ninerouter.ts заглушкой для пользователей, которые хотят
физически удалить из сборки пути с повышенными привилегиями.
Почему мы сохраняем эту возможность: 9router — необязательная локально устанавливаемая сопутствующая служба (аналог плагина WordPress), которая активируется исключительно по явному согласию пользователя.
§5 — Обратная запись учётных данных OmniRoute Cloud Sync (api/keys/[id]/route.js)
Заголовок раздела «§5 — Обратная запись учётных данных OmniRoute Cloud Sync (api/keys/[id]/route.js)»Исходные файлы:
src/lib/cloudSync.ts—syncToCloud()/updateLocalTokens().src/app/api/keys/[id]/route.ts— вызываетsyncKeysToCloudIfEnabled().
Условие срабатывания: isCloudEnabled() возвращает true (задаётся через панель управления) и
настроена переменная CLOUD_URL. Если оба параметра отключены, исходящий сетевой вызов
конечной точки Cloud не выполняется.
Поведение v3.8.5 (ошибка, которую Socket.dev корректно обнаружил):
updateLocalTokens() перезаписывала accessToken, refreshToken и
providerSpecificData данными из ответа Cloud, когда
cloudUpdatedAt > localUpdatedAt. Без HMAC, подписи или контрольной суммы.
Неверно настроенный или вредоносный CLOUD_URL (либо MITM-атака на канал) мог
незаметно подменить OAuth-токены провайдера.
Меры защиты в v3.8.6:
- Проверка HMAC:
verifyCloudSignature(rawBody, sigHeader)проверяет заголовокX-Cloud-Sig(HMAC-SHA256(OMNIROUTE_CLOUD_SYNC_SECRET, rawBody)) перед разбором JSON. Если секрет задан, подпись обязательна. Если он не задан (устаревший режим), в журнал записывается предупреждение, а ответ принимается — в v3.9 секрет станет обязательным. - Явное включение секретных полей:
accessToken/refreshToken/providerSpecificDataперезаписываются только приOMNIROUTE_CLOUD_SYNC_SECRETS=true. В режиме по умолчанию синхронизируются только метаданные, не содержащие учётных данных (expiresAt,status,lastError*,rateLimitedUntil,updatedAt). Это критическое изменение для пользователей, которые полагались на удалённую синхронизацию токенов: им необходимо явно включить эту возможность.
Почему мы сохраняем эту функцию: Cloud Sync — единственный способ для арендатора OmniRoute Cloud централизовать учётные данные команды. Исправление делает модель угроз прозрачной: «сервер подписывает, клиент проверяет, оператор явно разрешает».
Профиль сборки: minimal
Заголовок раздела «Профиль сборки: minimal»Пользователи, которым нужен совместимый с Socket артефакт, могут собрать его командой:
OMNIROUTE_BUILD_PROFILE=minimal npm run buildNormalModuleReplacementPlugin в webpack подменяет четыре модуля заглушками:
| Модуль | Заглушка |
|---|---|
src/mitm/cert/install.ts |
src/mitm/cert/install.stub.ts |
src/lib/zed-oauth/keychain-reader.ts |
src/lib/zed-oauth/keychain-reader.stub.ts |
src/lib/cloudSync.ts |
src/lib/cloudSync.stub.ts |
src/lib/services/installers/ninerouter.ts |
src/lib/services/installers/ninerouter.stub.ts |
Каждая заглушка экспортирует тот же интерфейс, но каждая функция во время выполнения выбрасывает
featureDisabledError(name). Маршруты, зависящие от отключённого
модуля, возвращают HTTP 503 с понятным сообщением вместо активации
чувствительного пути выполнения кода.
Полученный пакет предназначен для публикации под именем omniroute-secure. Инструкции по
публикации см. в docs/ops/PUBLISHING_SECURE.md.
Разделение плагина (отслеживается для v4)
Заголовок раздела «Разделение плагина (отслеживается для v4)»В долгосрочной перспективе мы планируем разделить пакет npm на модули, которые можно проверять по отдельности. Задачу для отслеживания хода работ см. в этапе v4 в трекере задач GitHub.
HagiCode
HagiCode — агентная среда разработки со структурированными процессами, параллельным выполнением несколькими агентами и интерфейсами Hero Dungeon.
Превращайте идеи в полезное ПО с более умным, быстрым и увлекательным агентным рабочим процессом.

- SmartСтруктурированные процессы превращают намерение в исполнимый путь от идеи до готового изменения.
- EfficientМультиагентные процессы параллельно продвигают исследование, реализацию и проверку.
- FunHero Dungeon делает длительную совместную разработку наглядной и увлекательной.