Socket.dev / supply-chain finding attestation (Deutsch)
§1 — Installation einer MITM-Root-CA (77484.js)
Abschnitt betitelt „§1 — Installation einer MITM-Root-CA (77484.js)“Quelldateien:
src/mitm/cert/install.ts— öffentliche FunktioneninstallCert()/uninstallCert()sowie plattformspezifische FunktioneninstallCertWindows/Mac/Linux.src/mitm/systemCommands.ts— gemeinsam genutzteexecFile- /spawn- / PowerShell-Hilfsfunktionen, die von den Installationspfaden verwendet werden.
Auslöser: Der Benutzer klickt im lokalen Dashboard unter
/dashboard/cli-tools/mitm auf „MITM-Proxy aktivieren“. Die Route ist
ausschließlich über Loopback erreichbar — siehe feste Regel Nr. 17 in
CLAUDE.md und src/server/authz/routeGuard.ts::isLocalOnlyPath(). Ein über
einen Tunnel offengelegtes JWT kann diesen Codepfad nicht auslösen.
Ausgeführte privilegierte Operationen (je Plattform):
| Betriebssystem | Befehl(e) |
|---|---|
| Windows | certutil -addstore Root <cert> über 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 | Aktualisierung der NSS-Datenbank pro Profil über certutil -d sql:<profile> |
Dies sind dieselben Befehle, die von mitmproxy, Charles Proxy, Fiddler und
Caddy verwendet werden. Dass sie in OmniRoute vorhanden sind, ist unter
docs/security/STEALTH_GUIDE.md dokumentiert.
Abhilfemaßnahme in v3.8.6:
runElevatedPowerShell()verwendet nicht länger-EncodedCommand <base64utf16le>. Die Nutzlast mit erhöhten Rechten wird in eine temporäre.ps1-Datei pro Aufruf geschrieben (Modus 0o600, innerhalb eines privatenmkdtempSync-Verzeichnisses) und über-Filereferenziert. Die Datei wird infinallygelöscht. Dadurch wird der typische, vom KI-Klassifikator von Socket.dev markierte Fingerabdruck einer Base64-kodierten Rechteerhöhung über PowerShell entfernt.installCertWindowsenthält einen Inline-BlockSECURITY-AUDITOR-NOTE:, der auf dieses Dokument verweist.
Warum wir diese Funktion beibehalten: Der MITM-Proxy ist eine dokumentierte
Funktion, die von docs/security/STEALTH_GUIDE.md und
docs/frameworks/MITM-PROXY.md verwendet wird. Seine Entfernung würde den
Funktionsumfang der Agent-Bridge beeinträchtigen.
§2 — Import von Zed-Anmeldedaten (app/api/providers/zed/import/route.js)
Abschnitt betitelt „§2 — Import von Zed-Anmeldedaten (app/api/providers/zed/import/route.js)“Quelldateien:
src/app/api/providers/zed/discover/route.ts(neu in v3.8.6)src/app/api/providers/zed/import/route.tssrc/lib/zed-oauth/keychain-reader.tssrc/lib/zed-oauth/credentialFingerprint.ts(neu in v3.8.6)
Auslöser: Der Benutzer klickt auf der Seite „Providers“ des lokalen Dashboards auf „Import from Zed“. Der Endpunkt ist durch requireManagementAuth geschützt. Der Zed-Editor selbst schreibt seine Provider-API-Schlüssel unter dokumentierten Dienstnamen in den Schlüsselbund des Betriebssystems — siehe https://zed.dev/docs/ai/llm-providers.
Verhalten in v3.8.5 (das von Socket.dev beanstandete Verhalten):
POST /import ermittelte die Anmeldedaten und speicherte sie automatisch in einem einzigen Roundtrip im lokalen SQLite-Speicher. Keine Bestätigung pro Konto, kein Fingerabdruck, lediglich „N Token gefunden, alle importiert“.
Schutzmaßnahme in v3.8.6 — Bestätigung in 2 Schritten:
POST /api/providers/zed/discovergibt{ candidates: [{ provider, service, account, fingerprint }] }zurück. Das unverarbeitete Token wird niemals übertragen. Der Fingerabdruck istsha256(service|account|token).slice(0,16).- Das Dashboard zeigt die Kandidatenliste an, der Betreiber wählt die zu
importierenden Einträge aus und sendet
{ confirmedAccounts: [{ service, account, fingerprint }] }anPOST /api/providers/zed/import. - Der Import-Endpunkt liest den Schlüsselbund erneut auf dem Server aus
und filtert nach
(service, account, fingerprint). Eine manipulierte oder erneut verwendete Discover-Antwort kann den Import-Endpunkt nicht dazu bringen, ein nicht zugehöriges Token zu speichern — wenn sich das aktive Token seit der Ermittlung geändert hat, stimmt der Fingerabdruck nicht mehr überein und die Anmeldedaten werden übersprungen.
Ein Umgebungs-Flag OMNIROUTE_ZED_IMPORT_LEGACY_ONE_STEP=true behält das
Verhalten von v3.8.5 für Betreiber bei, die ihre Automatisierung noch nicht
aktualisiert haben. Es wird in v3.9 entfernt.
Warum wir dies beibehalten: Der Zed-Import ist der benutzerfreundlichste Onboarding-Pfad für Benutzer, die Zed bereits verwenden und ihre Provider-Schlüssel in OmniRoute spiegeln möchten, ohne sie erneut einzufügen.
§3 — execFile / spawn / PowerShell mit erhöhten Rechten (21843.js)
Abschnitt betitelt „§3 — execFile / spawn / PowerShell mit erhöhten Rechten (21843.js)“Quelldateien: src/mitm/systemCommands.ts.
Grund für die Beanstandung: Der Chunk exportiert execFileWithPassword,
runElevatedPowerShell und den gemeinsam verwendeten Helfer quotePowerShell
erneut. Der KI-Klassifikator von Socket.dev erkennt sie als generisches
„Toolkit für Host-Ausführung und Rechteerhöhung“. Innerhalb von OmniRoute
werden sie ausschließlich vom MITM-Zertifikatinstallationspfad (§1) sowie von
execFileWithPassword für die Ausführung von sudo-Befehlen verwendet.
Schutzmaßnahmen in v3.8.6:
- Refaktorierung von
runElevatedPowerShell(siehe §1). - Ein Inline-Block
SECURITY-AUDITOR-NOTE:bei sowohlrunElevatedPowerShellals auchexecFileWithPassworddokumentiert die zugelassenen Aufrufer und die festgelegte Liste ausführbarer Dateien. - Der
spawn()-Aufruf vonexecFileWithPasswordenthält einenosemgrep-Markierung mit der Positivliste ausführbarer Dateien, die der Helfer entgegennehmen darf — es gibt keinen Pfad von Benutzereingaben zufinalCommand/finalArgs.
§4 / §6 — 9router-Dienst-Supervisor (api/services/9router/{start,restart}/route.js)
Abschnitt betitelt „§4 / §6 — 9router-Dienst-Supervisor (api/services/9router/{start,restart}/route.js)“Quelldateien:
src/app/api/services/9router/_lib.ts— Supervisor-Factory.src/app/api/services/9router/{start,stop,restart,status,install,update,auto-start}/route.ts.src/lib/services/ServiceSupervisor.ts— generisches Spawn-/Health-Poll-/Logpuffer-System.
Auslöser: Der Benutzer klickt auf der Seite für eingebettete Dienste im lokalen Dashboard auf „Install“ / „Start“.
Bereits vorhandene Schutzmaßnahmen:
- Alle
/api/services/*-Routen sind gemäßsrc/server/authz/routeGuard.tsLOCAL_ONLY (feste Regel Nr. 17). Die Loopback-Prüfung erfolgt vor jeder Authentifizierungsprüfung — selbst mit einem kompromittierten JWT sind diese Routen nicht erreichbar. - Der DB-Datensatz von 9router wird mit
status='not_installed', auto_start=0initialisiert (siehesrc/lib/db/migrations/071_services.sql:19). Der Dienst wird beim ersten Start nicht ausgeführt. spawn()wird mit dem Binärdateipfad aufgerufen, denresolveSpawnArgs(apiKey, PORT)insrc/lib/services/installers/ninerouter.tszurückgibt; dabei handelt es sich um eine feste Positivliste unterstützter Binärdateien.- Stdout/stderr wird im Arbeitsspeicher gepuffert (Obergrenze 5 MB, siehe
_lib.ts) — es erfolgt keine Speicherung auf dem Datenträger, sofern der Benutzer die Protokollierung nicht im Dashboard aktiviert.
Schutzmaßnahme in v3.8.6: keine funktionale Änderung. Das minimale
Build-Profil (OMNIROUTE_BUILD_PROFILE=minimal) ersetzt
src/lib/services/installers/ninerouter.ts durch einen Stub für Benutzer, die
die privilegierten Pfade physisch aus dem Bundle entfernen möchten.
Warum wir dies beibehalten: 9router ist ein optionaler, lokal installierbarer Begleitdienst (vergleichbar mit einem WordPress-Plugin) — eine ausdrückliche Aktivierung ist zwingend erforderlich.
§5 — Zurückschreiben von OmniRoute-Cloud-Sync-Anmeldedaten (api/keys/[id]/route.js)
Abschnitt betitelt „§5 — Zurückschreiben von OmniRoute-Cloud-Sync-Anmeldedaten (api/keys/[id]/route.js)“Quelldateien:
src/lib/cloudSync.ts—syncToCloud()/updateLocalTokens().src/app/api/keys/[id]/route.ts— ruftsyncKeysToCloudIfEnabled()auf.
Auslöser: isCloudEnabled() gibt true zurück (über das Dashboard festgelegt) und
CLOUD_URL ist konfiguriert. Wenn beide deaktiviert sind, erfolgt kein ausgehender Netzwerkaufruf an den Cloud-Endpunkt.
Verhalten in v3.8.5 (der Fehler, den Socket.dev korrekt erkannt hat):
updateLocalTokens() überschrieb accessToken, refreshToken und
providerSpecificData aus der Cloud-Antwort, wenn
cloudUpdatedAt > localUpdatedAt war. Kein HMAC, keine Signatur, keine Prüfsumme. Eine
falsch konfigurierte oder bösartige CLOUD_URL (oder ein MITM im Kommunikationskanal) konnte
OAuth-Token des Providers unbemerkt austauschen.
Gegenmaßnahmen in v3.8.6:
- HMAC-Verifizierung:
verifyCloudSignature(rawBody, sigHeader)prüft den HeaderX-Cloud-Sig(HMAC-SHA256(OMNIROUTE_CLOUD_SYNC_SECRET, rawBody)), bevor das JSON geparst wird. Wenn das Secret gesetzt ist, ist die Signatur erforderlich. Andernfalls (Legacy-Modus) wird eine Warnung protokolliert und die Antwort akzeptiert — ab v3.9 ist das Secret erforderlich. - Explizite Aktivierung geheimer Felder:
accessToken/refreshToken/providerSpecificDatawerden nur überschrieben, wennOMNIROUTE_CLOUD_SYNC_SECRETS=truegesetzt ist. Im Standardmodus werden nur Metadaten synchronisiert, die keine Anmeldedaten enthalten (expiresAt,status,lastError*,rateLimitedUntil,updatedAt). Dies ist eine inkompatible Änderung für Benutzer, die sich auf die Remote-Synchronisierung von Token verlassen haben — sie müssen diese explizit aktivieren.
Warum wir diese Funktion beibehalten: Cloud Sync ist die einzige Möglichkeit für einen OmniRoute-Cloud-Mandanten, Team-Anmeldedaten zentral zu verwalten. Die Korrektur bildet das Bedrohungsmodell ehrlich ab: „Der Server signiert, der Client verifiziert, der Betreiber stimmt zu.“
Build-Profil: minimal
Abschnitt betitelt „Build-Profil: minimal“Benutzer, die ein Socket-freundliches Artefakt benötigen, können es wie folgt erstellen:
OMNIROUTE_BUILD_PROFILE=minimal npm run buildDas webpack-Plugin NormalModuleReplacementPlugin ersetzt vier Module durch Stubs:
| Modul | 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 |
Jeder Stub exportiert dieselbe Schnittstelle, aber jede Funktion löst zur Laufzeit einen
featureDisabledError(name) aus. Routen, die vom deaktivierten
Modul abhängen, geben HTTP 503 mit einer eindeutigen Meldung zurück, anstatt den
sensiblen Codepfad zu aktivieren.
Das resultierende Bundle ist für die Veröffentlichung als omniroute-secure vorgesehen. Das
Veröffentlichungsverfahren ist unter docs/ops/PUBLISHING_SECURE.md beschrieben.
Plugin-Aufteilung (für v4 geplant)
Abschnitt betitelt „Plugin-Aufteilung (für v4 geplant)“Langfristig beabsichtigen wir, das npm-Paket in separat überprüfbare Module aufzuteilen. Das zugehörige Tracking-Issue finden Sie im v4-Meilenstein des GitHub-Issue-Trackers.
HagiCode
HagiCode ist ein agentischer Coding-Arbeitsplatz mit strukturierten Workflows, Multi-Agent-Ausführung und Hero-Dungeon-Ansichten.
Mit einem intelligenteren, schnelleren und unterhaltsameren agentischen Workflow wird aus Ideen nutzbare Software.

- SmartStrukturierte Workflows machen aus Absichten einen umsetzbaren Weg von der Idee bis zur Auslieferung.
- EfficientMulti-Agent-Workflows führen Recherche, Umsetzung und Prüfung parallel aus.
- FunHero Dungeon macht lange Coding-Sitzungen anschaulich und gemeinschaftlich.