# Sicherheits-Auditbericht: Datenabfluss und Data-Leakage-Risiken ## 1. Auftrag und Prüfgegenstand - **Rolle:** Security Auditor - **Ziel:** Technisch belastbare Bewertung, wie und wohin Daten bei Eingaben in der CLI ausgeleitet werden. - **System:** Kilo/OpenCode CLI (lokaler TUI-Client + lokaler HTTP-Server + externe Provider/Tools) - **Rechtsrahmen:** DSGVO, BDSG (technisch-rechtliche Einordnung) ## 2. Executive Summary Bei Eingabe im allgemeinen Prompt-Feld werden Daten nach dem lokalen Server-Hop an den konfigurierten LLM-Provider gesendet. Die primäre Exfiltrationsrichtung ist der aktive Modell-Endpoint. Zusätzliche Datenabflüsse entstehen durch Tool-Ausführungen (insb. `webfetch`, `websearch`, `codesearch`, MCP-Tools) sowie optional durch URL-basierte System-Instruktionen. **Wesentliche Feststellung:** Das größte Leakage-Risiko liegt nicht nur im LLM-Call selbst, sondern in **Folgeabflüssen durch Tool-Aufrufe** und konfigurationsabhängige Endpunkt-Overrides (`provider.*.options.baseURL`, `mcp.*.url`, `instructions` mit URL). ## 3. Methodik und Evidenz - Statische Code-Analyse der Request-Pfade (Prompt-Submit -> Session -> LLM -> Tools). - Analyse der Konfigurationsauflösung für Provider/MCP. - Shell-basierte Endpoint-Simulation für OpenAI-Responses-API. - Auswertung lokaler Konfigurationsdateien im Workspace. ### 3.1 Relevante Codepfade (Auszug) - Prompt-Submit: `packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx:616` - Session-Prompt-Route: `packages/opencode/src/server/routes/session.ts:730` - LLM-Streaming-Call: `packages/opencode/src/session/llm.ts:190` - Provider-Endpoint-Auflösung (`baseURL`/`api.url`): `packages/opencode/src/provider/provider.ts:83`, `packages/opencode/src/provider/provider.ts:1084` - Tool-Execution im Turn: `packages/opencode/src/session/processor.ts:182` - MCP Remote Transport: `packages/opencode/src/mcp/index.ts:331`, `packages/opencode/src/mcp/index.ts:338` - MCP Tool Call Weiterleitung: `packages/opencode/src/mcp/index.ts:135` ### 3.2 Shell-Simulation (OpenAI) Durchgeführter Probe-Call: ```bash curl -sS -o /tmp/kilo_openai_probe.out -w 'URL:%{url_effective}\nHTTP:%{http_code}\n' \ "https://api.openai.com/v1/responses" \ -H "Authorization: Bearer sk-invalid" \ -H "Content-Type: application/json" \ -d '{"model":"gpt-5.3-codex","input":"ping"}' ``` Ergebnis: `URL:https://api.openai.com/v1/responses`, `HTTP:401` (invalid_api_key). Das bestätigt den erwarteten Endpoint für OpenAI-Responses ohne lokale `baseURL`-Umleitung. ## 4. Technischer Datenabfluss: Was verlässt das System und wann? ## 4.1 Primärfluss bei normaler Texteingabe 1. User-Text wird im TUI erfasst. 2. Bei Submit: lokaler SDK-Aufruf an `session.prompt`. 3. Serverseitig startet LLM-Loop und ruft `streamText(...)` auf. 4. Der Request geht an den durch Provider/Model-Konfiguration aufgelösten externen Endpoint. **Datenkategorien im Primärfluss:** - Prompt-Inhalt des Users - Konversationshistorie (`messages`) - System-Prompts/Agent-Prompts - Tool-Ergebnisse aus vorherigen Schritten (falls im Verlauf enthalten) - ggf. aus Dateiinhalten erzeugte Textteile, wenn zuvor Read-/Ressourcen-Teile eingebunden wurden ## 4.2 Sekundärflüsse (Tool-induziert) Diese Flüsse können im selben Turn zusätzlich ausgelöst werden, wenn das Modell Tools aufruft. | Trigger | Technischer Pfad | Externer Endpoint | Potenziell abfließende Daten | | ----------------- | ------------------------ | -------------------------------------- | --------------------------------------------------------------------------------- | | `webfetch` Tool | `tool/webfetch.ts` | beliebige `http(s)` URL aus Tool-Param | URL und abrufbezogene Metadaten; Ergebnis kann in den Chatkontext zurückfließen | | `websearch` Tool | `tool/websearch.ts` | `POST https://mcp.exa.ai/mcp` | Suchquery + Parameter (`numResults`, `livecrawl`, `type`, `contextMaxCharacters`) | | `codesearch` Tool | `tool/codesearch.ts` | `POST https://mcp.exa.ai/mcp` | Suchquery + `tokensNum` | | MCP Remote Tool | `mcp/index.ts` | konfiguriertes `mcp..url` | Tool-Argumente und ggf. ressourcenbezogene Inhalte | | URL-Instruktionen | `session/instruction.ts` | URL aus `config.instructions` | Abruf der Remote-Instruktionstexte | ## 4.3 MCP-spezifische Abflüsse - Bei `type: "remote"` werden Verbindungen zu `mcp..url` aufgebaut (StreamableHTTP/SSE). - Tool-Calls werden an den MCP-Server durchgereicht. - Bei OAuth kann zusätzlich ein Authorization-Endpoint des MCP-Ökosystems angesprochen werden; lokaler Callback läuft auf `http://127.0.0.1:19876/mcp/oauth/callback` (`packages/opencode/src/mcp/oauth-provider.ts:35`). ## 5. Endpoint-Mapping und Konfigurationsabhängigkeit ## 5.1 Endpoint-Auflösung für LLM-Provider Der Zielendpoint ergibt sich aus folgender Reihenfolge: 1. `provider..options.baseURL` (falls gesetzt) 2. sonst `model.api.url` aus Provider/Model-Metadaten 3. sonst SDK-Default des jeweiligen Provider-Packages Nachweis: `packages/opencode/src/provider/provider.ts:83`, `packages/opencode/src/provider/provider.ts:1084`. ## 5.2 Beispiel: OpenAI + `gpt-5.3-codex` - Provider-Loader verwendet Responses-API (`sdk.responses(modelID)`) in `packages/opencode/src/provider/provider.ts:145`. - In der lokalen Models-Cache-Sicht ist für `openai` kein explizites `api` gesetzt. - Ohne `baseURL`-Override fällt die Laufzeit auf den OpenAI-Default zurück; die Probe zeigt `https://api.openai.com/v1/responses`. ## 5.3 Mögliche Endpunkte je Konfiguration (konkret) | Konfiguration | Effektiver Zieltyp | Beispiel | | --------------------------------------------------------------------- | -------------------------------------------- | --------------------------------------------- | | `provider.openai.options.baseURL = "https://proxy.example.com/v1"` | LLM-Request an Custom-Proxy | `POST https://proxy.example.com/v1/responses` | | `provider..models..provider.api = "https://llm.example.net/v1"` | Modell-API-URL überschreibt Katalogwert | Request an benutzerdefinierte URL | | `mcp.myserver = { type: "remote", url: "https://mcp.example.com" }` | MCP-Transport und Tool-Calls zu dieser URL | StreamableHTTP/SSE + Tool-Call | | `instructions = ["https://policy.example.org/agents.md"]` | Abruf externer Instruktionen beim Prompt-Bau | `GET https://policy.example.org/agents.md` | | Tool `webfetch` mit URL-Param | Direktaufruf beliebiger URL | `GET https://target.example/path` | ## 5.4 Beobachtete lokale Konfiguration (dieses Audit) - Gefundene Projektdatei: `.opencode/opencode.jsonc` - Darin: `provider.kilo.options = {}` und `mcp = {}` - Keine projektlokale OpenAI-`baseURL` in dieser Datei erkennbar. ## 6. DSGVO/BDSG-Einordnung (technisch-rechtlich) ## 6.1 Relevante Normen - **Art. 5 DSGVO:** Datenminimierung/Zweckbindung (Prompt- und Tool-Daten streng minimieren) - **Art. 6 DSGVO:** Rechtsgrundlage der jeweiligen Verarbeitung - **Art. 25 DSGVO:** Privacy by Design/Default (restriktive Defaults für Tools/Endpoints) - **Art. 28 DSGVO:** AV-Verträge mit externen Verarbeitern - **Art. 32 DSGVO:** TOMs (Zugriff, Verschlüsselung, Monitoring, Incident Handling) - **Art. 44 ff. DSGVO:** Drittlandübermittlungen bei nicht-EU-Endpoints - **Art. 30 DSGVO:** Verzeichnis der Verarbeitungstätigkeiten - **BDSG (ergänzend):** insb. Beschäftigtendatenbezug nach § 26 BDSG im Unternehmenskontext ## 6.2 Bewertung der Konformitätsrisiken - **Erhöhtes Risiko**, wenn Prompts/Anhänge personenbezogene oder vertrauliche Inhalte enthalten und Tools externe Calls auslösen. - **Erhöhtes Drittland-Risiko** bei US-/Nicht-EU-Providern ohne saubere Transfer-Governance. - **Governance-Risiko** durch fehlende Endpoint-Allowlist und zu permissive Tool-Rechte. ## 7. Befunde (auditorisch) | ID | Befund | Risiko | | ---- | ------------------------------------------------------------------------------------------------------------------------ | ----------------- | | F-01 | Primäre Prompt-Daten werden an den aktiven LLM-Endpoint übertragen; Endpoint kann per Konfiguration umgebogen werden. | Hoch | | F-02 | Tool-Aufrufe können zusätzliche externe Endpunkte adressieren (`webfetch`, Exa, MCP). | Hoch | | F-03 | MCP-Remote-Konfiguration erlaubt flexible externe Ziele; OAuth erweitert Datenfluss auf Auth-Infrastruktur. | Mittel-Hoch | | F-04 | URL-basierte `instructions` erlauben externe Inhaltsnachladung beim Prompt-Bau. | Mittel | | F-05 | Telemetrie in `LLM.stream` ist konfiguriert mit `recordInputs: false`, `recordOutputs: false` (positiver Kontrollpunkt). | Niedrig (positiv) | ## 8. Maßnahmenkatalog (priorisiert) 1. **Endpoint-Allowlist erzwingen** (Provider-`baseURL`, MCP-`url`, `webfetch` Ziele auf genehmigte Domains begrenzen). 2. **DLP/Redaction vor Versand** (PII/Secrets-Scanner für Prompt, Attachments, Tool-Argumente). 3. **Tooling per Default restriktiv** (insb. `webfetch`, externe MCP-Server nur per expliziter Freigabe). 4. **MCP-Härtung** (nur signierte/vertrauenswürdige Server, feste Header-Policies, kurze Timeouts, least privilege). 5. **DSGVO-Transfer-Set** (AVV, SCC, TIA, Subprozessor-Transparenz je Endpoint). 6. **Nachvollziehbarkeit** (auditfeste Logs zu Endpunktwahl + Tool-Exfiltration, ohne Inhaltslogging sensibler Nutzdaten). 7. **Konfigurations-Governance** (CI-Policy-Checks auf verbotene `baseURL`/`mcp.url`/`instructions`-Hosts). ## 9. Schlussbewertung Die Anwendung besitzt einen nachvollziehbaren Primärfluss (Prompt -> LLM-Provider), jedoch ist das Data-Leakage-Risiko maßgeblich durch **konfigurierbare Endpunkte** und **toolgetriebene Sekundärflüsse** bestimmt. Für OpenAI `gpt-5.3-codex` zeigt die technische Probe den Responses-Endpoint `https://api.openai.com/v1/responses` bei fehlendem Override. Aus Datenschutzsicht ist eine belastbare Compliance nur mit strikter Endpoint-/Tool-Governance, DLP und dokumentierten Transfermechanismen erreichbar.