Ir al contenido
OmniRoute source

Socket.dev / supply-chain finding attestation (Español)

§1 — Instalación de la CA raíz para MITM (77484.js)

Sección titulada «§1 — Instalación de la CA raíz para MITM (77484.js)»

Archivos fuente:

  • src/mitm/cert/install.ts — funciones públicas installCert() / uninstallCert(), e implementaciones por plataforma installCertWindows/Mac/Linux.
  • src/mitm/systemCommands.ts — utilidades compartidas de execFile / spawn / PowerShell utilizadas por las rutas de instalación.

Activador: el usuario hace clic en «Habilitar proxy MITM» en el panel local en /dashboard/cli-tools/mitm. La ruta solo es accesible mediante loopback; consulte la regla estricta n.º 17 en CLAUDE.md y src/server/authz/routeGuard.ts::isLocalOnlyPath(). Un JWT filtrado y expuesto mediante un túnel no puede activar esta ruta de código.

Operaciones con privilegios realizadas (por plataforma):

SO Comando(s)
Windows certutil -addstore Root <cert> mediante 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 actualización de la base de datos NSS de cada perfil mediante certutil -d sql:<profile>

Estos son los mismos comandos utilizados por mitmproxy, Charles Proxy, Fiddler y Caddy. El hecho de que existan en OmniRoute está documentado en docs/security/STEALTH_GUIDE.md.

Mitigación de v3.8.6:

  • runElevatedPowerShell() ya no utiliza -EncodedCommand <base64utf16le>. La carga útil con privilegios elevados se escribe en un archivo temporal .ps1 por llamada (modo 0o600, dentro de un directorio privado de mkdtempSync) y se referencia mediante -File. El archivo se desvincula en finally. Esto elimina la conocida huella de elevación mediante PowerShell y base64 marcada por el clasificador de IA de Socket.dev.
  • installCertWindows contiene un bloque SECURITY-AUDITOR-NOTE: en línea que remite a este documento.

Por qué lo conservamos: el proxy MITM es una funcionalidad documentada utilizada por docs/security/STEALTH_GUIDE.md y docs/frameworks/MITM-PROXY.md. Eliminarlo rompería el conjunto de funcionalidades del puente de agentes.


§2 — Importación de credenciales de Zed (app/api/providers/zed/import/route.js)

Sección titulada «§2 — Importación de credenciales de Zed (app/api/providers/zed/import/route.js)»

Archivos fuente:

  • src/app/api/providers/zed/discover/route.ts (nuevo en v3.8.6)
  • src/app/api/providers/zed/import/route.ts
  • src/lib/zed-oauth/keychain-reader.ts
  • src/lib/zed-oauth/credentialFingerprint.ts (nuevo en v3.8.6)

Desencadenante: el usuario hace clic en “Importar desde Zed” en la página de Proveedores del panel local. El acceso al endpoint está controlado por requireManagementAuth. El propio editor Zed almacena sus claves de API de proveedores en el llavero del sistema operativo con nombres de servicio documentados; consulte https://zed.dev/docs/ai/llm-providers.

Comportamiento de v3.8.5 (el señalado por Socket.dev):

POST /import detectaba las credenciales y las guardaba automáticamente en el almacén SQLite local en una sola operación de ida y vuelta. Sin confirmación por cuenta ni huella digital; simplemente: “se encontraron N tokens, todos importados”.

Mitigación de v3.8.6 — confirmación en 2 pasos:

  1. POST /api/providers/zed/discover devuelve { candidates: [{ provider, service, account, fingerprint }] }. El token sin procesar nunca se transmite. La huella digital es sha256(service|account|token).slice(0,16).
  2. El panel muestra la lista de candidatos, el operador selecciona cuáles desea importar y envía { confirmedAccounts: [{ service, account, fingerprint }] } a POST /api/providers/zed/import.
  3. El endpoint de importación vuelve a leer el llavero en el servidor y filtra por (service, account, fingerprint). Una respuesta de detección manipulada o reproducida no puede engañar al endpoint de importación para que guarde un token no relacionado: si el token activo ha cambiado desde la detección, la huella digital ya no coincide y se omite la credencial.

Una variable de entorno OMNIROUTE_ZED_IMPORT_LEGACY_ONE_STEP=true conserva el comportamiento de v3.8.5 para los operadores que aún no hayan actualizado su automatización. Se eliminará en v3.9.

Por qué lo mantenemos: la importación desde Zed es la opción de incorporación más sencilla para los usuarios que ya utilizan Zed y desean replicar sus claves de proveedores en OmniRoute sin tener que volver a pegarlas.


§3 — execFile / spawn / PowerShell con privilegios elevados (21843.js)

Sección titulada «§3 — execFile / spawn / PowerShell con privilegios elevados (21843.js)»

Archivos fuente: src/mitm/systemCommands.ts.

Por qué se señaló: el fragmento vuelve a exportar execFileWithPassword, runElevatedPowerShell y la utilidad compartida quotePowerShell. El clasificador de IA de Socket.dev los identifica como un conjunto genérico de herramientas de “ejecución en el host + elevación de privilegios”. Dentro de OmniRoute, solo los utiliza la ruta de instalación del certificado MITM (§1), así como execFileWithPassword para ejecutar comandos sudo.

Mitigación de v3.8.6:

  • Refactorización de runElevatedPowerShell (consulte §1).
  • Un bloque SECURITY-AUDITOR-NOTE: en línea, tanto en runElevatedPowerShell como en execFileWithPassword, documenta los llamadores incluidos en la lista de permitidos y la lista fija de ejecutables.
  • La llamada spawn() de execFileWithPassword incluye un marcador nosemgrep con la lista de ejecutables permitidos que la utilidad puede recibir; no existe ninguna ruta desde la entrada del usuario hasta finalCommand/finalArgs.

§4 / §6 — Supervisor del servicio 9router (api/services/9router/{start,restart}/route.js)

Sección titulada «§4 / §6 — Supervisor del servicio 9router (api/services/9router/{start,restart}/route.js)»

Archivos fuente:

  • src/app/api/services/9router/_lib.ts — fábrica del supervisor.
  • src/app/api/services/9router/{start,stop,restart,status,install,update,auto-start}/route.ts.
  • src/lib/services/ServiceSupervisor.ts — generación genérica de procesos / sondeo de estado / búfer de registros.

Desencadenante: el usuario hace clic en “Instalar” / “Iniciar” en la página de servicios integrados del panel local.

Protecciones ya implementadas:

  • Todas las rutas /api/services/* son LOCAL_ONLY según src/server/authz/routeGuard.ts (regla estricta n.º 17). La restricción al bucle invertido se aplica antes de cualquier comprobación de autenticación; un JWT filtrado no puede acceder a ellas.
  • La fila de 9router en la base de datos se inicializa como status='not_installed', auto_start=0 (consulte src/lib/db/migrations/071_services.sql:19). El servicio no se inicia en el primer arranque.
  • Se llama a spawn() con la ruta del binario devuelta por resolveSpawnArgs(apiKey, PORT) en src/lib/services/installers/ninerouter.ts, que utiliza una lista fija de binarios compatibles permitidos.
  • La salida estándar y de error se almacenan en un búfer en memoria (con un límite de 5 MB; consulte _lib.ts); no se escribe nada en disco a menos que el usuario habilite el registro desde el panel.

Mitigación de v3.8.6: sin cambios funcionales. El perfil de compilación mínimo (OMNIROUTE_BUILD_PROFILE=minimal) sustituye src/lib/services/installers/ninerouter.ts por un stub para los usuarios que deseen eliminar físicamente las rutas con privilegios del paquete.

Por qué lo mantenemos: 9router es un servicio complementario opcional que se puede instalar localmente (similar a un plugin de WordPress); requiere una aceptación explícita y estricta.


§5 — Escritura de credenciales mediante OmniRoute Cloud Sync (api/keys/[id]/route.js)

Sección titulada «§5 — Escritura de credenciales mediante OmniRoute Cloud Sync (api/keys/[id]/route.js)»

Archivos fuente:

  • src/lib/cloudSync.ts — syncToCloud() / updateLocalTokens().
  • src/app/api/keys/[id]/route.ts — invoca syncKeysToCloudIfEnabled().

Activador: isCloudEnabled() devuelve true (configurado desde el panel) y CLOUD_URL está configurada. Si ambas opciones están desactivadas, no se realiza ninguna llamada de red saliente al endpoint de Cloud.

Comportamiento de v3.8.5 (el error que Socket.dev detectó correctamente):

updateLocalTokens() sobrescribía accessToken, refreshToken y providerSpecificData a partir de la respuesta de Cloud cuando cloudUpdatedAt > localUpdatedAt. Sin HMAC, firma ni suma de comprobación. Una CLOUD_URL mal configurada u hostil (o un ataque MITM en el canal) podía sustituir silenciosamente los tokens OAuth del proveedor.

Mitigación en v3.8.6:

  1. Verificación HMAC: verifyCloudSignature(rawBody, sigHeader) comprueba el encabezado X-Cloud-Sig (HMAC-SHA256(OMNIROUTE_CLOUD_SYNC_SECRET, rawBody)) antes de analizar el JSON. Si el secreto está configurado, la firma es obligatoria. Si no lo está (modo heredado), se registra una advertencia y se acepta la respuesta; el secreto será obligatorio en v3.9.
  2. Activación explícita de campos secretos: accessToken / refreshToken / providerSpecificData solo se sobrescriben cuando OMNIROUTE_CLOUD_SYNC_SECRETS=true. El modo predeterminado sincroniza únicamente metadatos que no son credenciales (expiresAt, status, lastError*, rateLimitedUntil, updatedAt). Este es un cambio incompatible para los usuarios que dependían de la sincronización remota de tokens: deben activarla explícitamente.

Por qué lo mantenemos: Cloud Sync es la única forma de que un tenant de OmniRoute Cloud centralice las credenciales del equipo. La corrección deja claro el modelo de amenazas: “el servidor firma, el cliente verifica y el operador activa la función.”


Para los usuarios que necesiten un artefacto compatible con Socket, compilen con:

Ventana de terminal
OMNIROUTE_BUILD_PROFILE=minimal npm run build

El NormalModuleReplacementPlugin de webpack sustituye cuatro módulos por stubs:

Módulo Stub
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

Cada stub exporta la misma interfaz, pero todas las funciones lanzan un featureDisabledError(name) en tiempo de ejecución. Las rutas que dependen del módulo deshabilitado devuelven HTTP 503 con un mensaje claro, en lugar de activar la ruta de código sensible.

El bundle resultante está destinado a publicarse como omniroute-secure. Consulte docs/ops/PUBLISHING_SECURE.md para ver el procedimiento de publicación.


A largo plazo, tenemos previsto dividir el paquete npm en módulos que puedan auditarse por separado. Consulta el hito de v4 en el sistema de seguimiento de incidencias de GitHub para ver la incidencia de seguimiento.


Código fuente de OmniRoute (a58000c7685f)

HagiCode

HagiCode es un espacio de trabajo de programación con agentes, flujos estructurados, ejecución multiagente y vistas de Hero Dungeon.

Convierte ideas en software útil con un flujo de trabajo con agentes más inteligente, rápido y ameno.

Interfaz principal de HagiCode con tema claro
  • SmartLos flujos estructurados convierten la intención en un itinerario ejecutable desde la idea hasta la entrega.
  • EfficientLos flujos multiagente permiten avanzar en paralelo con la investigación, implementación y revisión.
  • FunHero Dungeon hace que las largas sesiones de programación sean visuales y colaborativas.
Visitar HagiCode