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úblicasinstallCert()/uninstallCert(), e implementaciones por plataformainstallCertWindows/Mac/Linux.src/mitm/systemCommands.ts— utilidades compartidas deexecFile/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.ps1por llamada (modo 0o600, dentro de un directorio privado demkdtempSync) y se referencia mediante-File. El archivo se desvincula enfinally. Esto elimina la conocida huella de elevación mediante PowerShell y base64 marcada por el clasificador de IA de Socket.dev.installCertWindowscontiene un bloqueSECURITY-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.tssrc/lib/zed-oauth/keychain-reader.tssrc/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:
POST /api/providers/zed/discoverdevuelve{ candidates: [{ provider, service, account, fingerprint }] }. El token sin procesar nunca se transmite. La huella digital essha256(service|account|token).slice(0,16).- El panel muestra la lista de candidatos, el operador selecciona cuáles desea importar y envía
{ confirmedAccounts: [{ service, account, fingerprint }] }aPOST /api/providers/zed/import. - 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 enrunElevatedPowerShellcomo enexecFileWithPassword, documenta los llamadores incluidos en la lista de permitidos y la lista fija de ejecutables. - La llamada
spawn()deexecFileWithPasswordincluye un marcadornosemgrepcon la lista de ejecutables permitidos que la utilidad puede recibir; no existe ninguna ruta desde la entrada del usuario hastafinalCommand/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únsrc/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(consultesrc/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 porresolveSpawnArgs(apiKey, PORT)ensrc/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— invocasyncKeysToCloudIfEnabled().
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:
- Verificación HMAC:
verifyCloudSignature(rawBody, sigHeader)comprueba el encabezadoX-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. - Activación explícita de campos secretos:
accessToken/refreshToken/providerSpecificDatasolo se sobrescriben cuandoOMNIROUTE_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.”
Perfil de compilación: minimal
Sección titulada «Perfil de compilación: minimal»Para los usuarios que necesiten un artefacto compatible con Socket, compilen con:
OMNIROUTE_BUILD_PROFILE=minimal npm run buildEl 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.
División del plugin (prevista para v4)
Sección titulada «División del plugin (prevista para v4)»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.
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.

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