コンテンツにスキップ
OmniRoute source

Socket.dev / supply-chain finding attestation (日本語)

§1 — MITMルートCAのインストール(77484.js)

Section titled “§1 — MITMルートCAのインストール(77484.js)”

ソースファイル:

  • src/mitm/cert/install.ts — 公開 installCert() / uninstallCert()、 プラットフォーム別の installCertWindows/Mac/Linux。
  • src/mitm/systemCommands.ts — インストールパスで使用される、共有の execFile / spawn / PowerShell ヘルパー。

トリガー: ユーザーがローカルダッシュボードの /dashboard/cli-tools/mitm で「MITMプロキシを有効化」をクリックします。このルートは ループバック専用です — CLAUDE.md の厳格なルール #17 および src/server/authz/routeGuard.ts::isLocalOnlyPath() を参照してください。トンネル経由で 漏洩したJWTから、このコードパスをトリガーすることはできません。

実行される特権操作(プラットフォーム別):

OS コマンド
Windows UAC経由で certutil -addstore Root <cert>
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 certutil -d sql:<profile> を介したプロファイルごとのNSS DB更新

これらは、mitmproxy、Charles Proxy、Fiddler、および Caddyで使用されているものと同じコマンドです。これらがOmniRouteに存在することは、 docs/security/STEALTH_GUIDE.md に記載されています。

v3.8.6 の緩和策:

  • runElevatedPowerShell() は、-EncodedCommand <base64utf16le> を使用しなくなりました。 昇格されたペイロードは、呼び出しごとの一時 .ps1 ファイル(モード 0o600、 非公開の mkdtempSync ディレクトリ内)に書き込まれ、-File を介して参照されます。 このファイルは finally でリンク解除されます。これにより、Socket.devのAI 分類器によってフラグ付けされた、PowerShell経由のbase64権限昇格という典型的な フィンガープリントが除去されます。
  • installCertWindows には、ここを参照するインラインの SECURITY-AUDITOR-NOTE: ブロックがあります。

これを維持する理由: MITMプロキシは、 docs/security/STEALTH_GUIDE.md および docs/frameworks/MITM-PROXY.md で使用される 文書化済みの機能です。これを削除すると、エージェントブリッジ機能群が 動作しなくなります。


§2 — Zed 認証情報のインポート(app/api/providers/zed/import/route.js)

Section titled “§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.ts
  • src/lib/zed-oauth/keychain-reader.ts
  • src/lib/zed-oauth/credentialFingerprint.ts (v3.8.6 で新規追加)

トリガー: ユーザーがローカルダッシュボードのプロバイダーページで「Zed からインポート」をクリックしたとき。エンドポイントは requireManagementAuth によって保護されています。Zed エディター自体は、ドキュメントに記載されたサービス名で、プロバイダーの API キーを OS のキーチェーンに書き込みます — https://zed.dev/docs/ai/llm-providers を参照してください。

v3.8.5 の動作(Socket.dev が指摘したもの):

POST /import は認証情報を検出し、1 回のラウンドトリップでローカルの SQLite ストアに自動保存していました。アカウントごとの確認もフィンガープリントもなく、単に「N 個のトークンが見つかり、すべてインポートされました」という動作でした。

v3.8.6 の緩和策 — 2 段階確認:

  1. POST /api/providers/zed/discover は { candidates: [{ provider, service, account, fingerprint }] } を返します。生のトークンが送信されることは決してありません。フィンガープリントは sha256(service|account|token).slice(0,16) です。
  2. ダッシュボードに候補一覧が表示され、オペレーターがインポート対象を選択すると、{ confirmedAccounts: [{ service, account, fingerprint }] } が POST /api/providers/zed/import に送信されます。
  3. インポートエンドポイントはサーバー上でキーチェーンを再読み込みし、(service, account, fingerprint) でフィルタリングします。改ざんまたはリプレイされた discover レスポンスによって、無関係なトークンをインポートエンドポイントに保存させることはできません — discover の実行後に実際のトークンが変更されていれば、フィンガープリントが一致しなくなるため、その認証情報はスキップされます。

OMNIROUTE_ZED_IMPORT_LEGACY_ONE_STEP=true 環境変数フラグにより、まだ自動化を更新していないオペレーター向けに v3.8.5 の動作が維持されます。このフラグは v3.9 で削除される予定です。

維持する理由: Zed をすでに使用しており、プロバイダーキーを再度貼り付けることなく OmniRoute に複製したいユーザーにとって、Zed インポートは最も使いやすいオンボーディング手段です。


§3 — execFile / spawn / 管理者権限での PowerShell(21843.js)

Section titled “§3 — execFile / spawn / 管理者権限での PowerShell(21843.js)”

ソースファイル: src/mitm/systemCommands.ts。

指摘された理由: このチャンクは execFileWithPassword、runElevatedPowerShell、および共有の quotePowerShell ヘルパーを再エクスポートします。Socket.dev の AI 分類器は、これらを汎用的な「ホスト上での実行 + 権限昇格ツールキット」と見なします。OmniRoute 内では、これらは MITM 証明書のインストール処理(§1)と、sudo コマンド実行用の execFileWithPassword でのみ使用されます。

v3.8.6 の緩和策:

  • runElevatedPowerShell のリファクタリング(§1 を参照)。
  • runElevatedPowerShell と execFileWithPassword の両方にあるインラインの SECURITY-AUDITOR-NOTE: ブロックで、許可リストに登録された呼び出し元と固定された実行可能ファイル一覧を文書化。
  • execFileWithPassword の spawn() 呼び出しには、このヘルパーが受け取ることを許可された実行可能ファイルの許可リストとともに nosemgrep マーカーが付いています — ユーザー入力から finalCommand/finalArgs へ到達する経路はありません。

§4 / §6 — 9router サービススーパーバイザー(api/services/9router/{start,restart}/route.js)

Section titled “§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 — 汎用的な spawn / ヘルスポーリング / ログバッファー。

トリガー: ユーザーがローカルダッシュボード内の組み込みサービスページで「インストール」/「開始」をクリックしたとき。

既存の保護策:

  • src/server/authz/routeGuard.ts の規定(厳格なルール #17)により、すべての /api/services/* ルートは LOCAL_ONLY です。ループバックの強制はあらゆる認証チェックより前に行われるため、JWT が漏洩してもこれらのルートには到達できません。
  • 9router の DB 行は status='not_installed', auto_start=0 としてシードされます(src/lib/db/migrations/071_services.sql:19 を参照)。このサービスは初回起動時には開始されません。
  • spawn() は src/lib/services/installers/ninerouter.ts 内の resolveSpawnArgs(apiKey, PORT) が返すバイナリパスを使用して呼び出されます。これは、サポート対象バイナリの固定された許可リストです。
  • Stdout/stderr はメモリ内でバッファリングされます(上限 5 MB、_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)

Section titled “§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 が正しく検出したバグ):

cloudUpdatedAt > localUpdatedAt の場合、updateLocalTokens() は Cloud のレスポンスに 含まれる値で accessToken、refreshToken、providerSpecificData を上書きしていました。 HMAC、署名、チェックサムはいずれもありませんでした。設定ミスのある、または悪意のある CLOUD_URL(あるいは通信経路上の MITM)によって、プロバイダーの OAuth トークンが 密かに差し替えられる可能性がありました。

v3.8.6 での緩和策:

  1. HMAC 検証: verifyCloudSignature(rawBody, sigHeader) は、JSON を解析する前に X-Cloud-Sig ヘッダー(HMAC-SHA256(OMNIROUTE_CLOUD_SYNC_SECRET, rawBody))を検証します。シークレットが設定されている場合、署名は必須です。 設定されていない場合(レガシーモード)は、警告をログに記録したうえでレスポンスを 受け入れます。v3.9 ではシークレットが必須になります。
  2. シークレットフィールドのオプトイン: accessToken / refreshToken / providerSpecificData は、OMNIROUTE_CLOUD_SYNC_SECRETS=true の場合にのみ 上書きされます。デフォルトモードでは、認証情報以外のメタデータ(expiresAt、 status、lastError*、rateLimitedUntil、updatedAt)のみを同期します。 これは、リモートトークン同期に依存していたユーザーにとっては破壊的変更です。 そのようなユーザーは明示的にオプトインする必要があります。

これを維持する理由: Cloud Sync は、OmniRoute Cloud テナントがチームの認証情報を 一元管理するための唯一の方法です。この修正により、脅威モデルが実態に即したものになります: 「サーバーが署名し、クライアントが検証し、運用者がオプトインする。」


Socket と相性のよい成果物が必要なユーザーは、次のコマンドでビルドしてください:

ターミナルウィンドウ
OMNIROUTE_BUILD_PROFILE=minimal npm run build

webpack の NormalModuleReplacementPlugin は、4 つのモジュールをスタブにエイリアスします:

モジュール スタブ
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 で追跡)

Section titled “プラグインの分割(v4 で追跡)”

長期的には、npm package を個別に監査可能なモジュールへ分割する予定です。 追跡中の issue については、GitHub issue tracker の v4 milestone を参照してください。


OmniRoute ソースコード (a58000c7685f)

HagiCode

HagiCode は構造化ワークフロー、マルチエージェント実行、Hero Dungeon ビューを備えたエージェント型コーディングワークスペースです。

よりスマートで速く、楽しいエージェント型ワークフローで、使いやすいソフトウェアを形にします。

HagiCode ライトテーマのメイン画面
  • Smart構造化ワークフローは意図をアイデアから変更のリリースまで実行可能な道筋にします。
  • Efficientマルチエージェントのワークフローで調査、実装、レビューを並行して進めます。
  • FunHero Dungeon により長時間のコーディングを視覚的で協力的な体験にします。
HagiCode を見る