[SSRF-Blockierung des privaten Netzwerks bei Audiotranskription nach Upgrade auf v2026.4.14] - SSRF Block on Private Network Audio Transcription After v2026.4.14 Upgrade
Sprachnachrichten-Transkription an selbst gehostete STT-Endpunkte auf privaten IPs schlΓ€gt mit SsrFBlockedError fehl, selbst wenn models.providers.*.request.allowPrivateNetwork konfiguriert ist, verursacht durch zwei kaskadierende Bugs bei der Provider-AnfrageauflΓΆsung.
π Symptome
PrimΓ€re FehlerΓ€uΓerung
Audio-Transkriptionsanfragen an OpenAI-kompatible Endpunkte auf privaten LAN-IPs werden mit einem SSRF-VerstoΓ blockiert, trotz expliziter Konfiguration, die den Zugriff auf private Netzwerke erlaubt.
[security] blocked URL fetch (url-fetch) target=http://192.168.x.x:5092/v1/audio/transcriptions reason=Blocked hostname or private/internal/special-use IP address
[media-understanding] audio: failed (0/1) reason=SsrFBlockedErrorBetroffene Operationen
- Sprachnachrichten-Transkription ΓΌber
parakeet-Modell auf selbst gehosteten STT-Endpunkten - Jeder
media.audio-Tool-Aufruf, der auf private/interne IP-Adressen abzielt - OpenAI-kompatible API-Endpunkte auf LAN-Adressen (z.B.
192.168.x.x,10.x.x.x,172.16.x.x)
Konfiguration, die funktionieren sollte
Die folgende Konfiguration ist der dokumentierte Ansatz zur Aktivierung des privaten Netzwerkzugriffs fΓΌr STT-Anbieter:
{
"models": {
"providers": {
"openai": {
"apiKey": "local",
"baseUrl": "http://192.168.x.x:5092/v1",
"request": {
"allowPrivateNetwork": true
}
}
}
},
"tools": {
"media": {
"audio": {
"enabled": true,
"models": [{ "provider": "openai", "model": "parakeet" }]
}
}
}
}Versionskontext
| Version | Verhalten |
|---|---|
| v2026.4.12 | β Funktioniert korrekt |
| v2026.4.13 | β Funktioniert korrekt |
| v2026.4.14 | β SSRF blockiert β Regression eingefΓΌhrt |
Diagnose-Befehlsausgabe
Wenn die Fehlersuche aktiviert ist, kann Folgendes in den Logs erscheinen:
# Enable debug logging to trace request resolution
DEBUG=openclaw:* node index.js
# Expected SSRF block in output:
[security] blocked URL fetch (url-fetch) target=http://192.168.x.x:5092/v1/audio/transcriptions reason=Blocked hostname or private/internal/special-use IP addressπ§ Ursache
Γbersicht
Zwei unabhΓ€ngige Bugs in der Version v2026.4.14 bilden eine Kaskade, die die allowPrivateNetwork-Konfiguration aus den Anbieter-Anfrageeinstellungen stillschweigend entfernt. Beide Bugs mΓΌssen vorhanden sein, um den Fehler zu reproduzieren, und beide mΓΌssen behoben werden, um das korrekte Verhalten wiederherzustellen.
Bug 1: resolveProviderExecutionContext Entfernt allowPrivateNetwork aus der Anbieter-Konfiguration
Betroffene Datei: runner.entries-*.js (dist-Datei)
Codepfad:
Die Funktion resolveProviderExecutionContext konstruiert das request-Objekt, das an transcribeAudio ΓΌber die folgende ZusammenfΓΌhrungskette ΓΌbergeben wird:
javascript request: mergeProviderRequestOverrides( sanitizeConfiguredProviderRequest(params.config?.request), sanitizeConfiguredProviderRequest(params.entry.request) )
Grundursache:
Die Funktion fΓΌhrt nur zusammen:
params.config?.requestβ Request-Konfiguration auf Tool-Ebene (vontools.media.audio.request)params.entry.requestβ Request-Γberschreibungen auf Entry-Ebene
Entscheidend ist, dass die Anbieter-Level-Konfiguration (models.providers.<id>.request) niemals in diese ZusammenfΓΌhrung einbezogen wird. Die Funktion sanitizeConfiguredProviderRequest filtert explizit nur diese Felder:
javascript // Fields preserved by sanitizeConfiguredProviderRequest const ALLOWED_REQUEST_FIELDS = [‘headers’, ‘auth’, ‘proxy’, ’tls’]; // Note: ‘allowPrivateNetwork’ is intentionally NOT in this list
Ergebnis: Selbst wenn ein Betreiber korrekt konfiguriert:
json “models”: { “providers”: { “openai”: { “request”: { “allowPrivateNetwork”: true } } } }
Dieser Wert wird stillschweigend verworfen, da die Anbieterkonfiguration wΓ€hrend der Konstruktion des Request-Objekts fΓΌr die Audio-Transkription niemals abgefragt wird.
Bug 2: resolveProviderRequestPolicyConfig Ignoriert allowPrivateNetwork in params.request
Betroffene Datei: provider-request-config-*.js (dist-Datei)
Codepfad:
Die Funktion resolveProviderRequestPolicyConfig gibt die aufgelΓΆste Sicherheitsrichtlinie zurΓΌck:
javascript allowPrivateNetwork: params.allowPrivateNetwork ?? false
Grundursache:
Die Funktion prΓΌft nur params.allowPrivateNetwork β ein direkter Parameter, den Aufrufer explizit ΓΌbergeben mΓΌssen. Allerdings leiten alle Audio-Transkriptions-Aufrufer ihre Request-Konfiguration von resolveProviderHttpRequestConfig ab und ΓΌbergeben sie als request: params.request.
Die Aufrufer (z.B. transcribeOpenAiCompatibleAudio, transcribeDeepgramAudio) setzen:
javascript { request: resolveProviderHttpRequestConfig({ model: params.model, provider: params.provider, // allowPrivateNetwork IS present here from Bug 1 fix }) }
Aber resolveProviderRequestPolicyConfig empfΓ€ngt params.request?.allowPrivateNetwork und prΓΌft es nie. Der Wert wird nur aus dem flachen Parameter params.allowPrivateNetwork gelesen, den Audio-Aufrufer nicht explizit setzen.
Ergebnis: Selbst wenn Bug 1 behoben wΓ€re und allowPrivateNetwork korrekt in params.request platziert wΓΌrde, wΓΌrde Bug 2 es wΓ€hrend der RichtlinienauflΓΆsung stillschweigend verwerfen.
Fehlersequenzdiagramm
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β CORRECT BEHAVIOR (v2026.4.12/13) β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ β models.providers.openai.request.allowPrivateNetwork = true β β β β β βΌ β β resolveProviderExecutionContext() merges provider config β β β β β βΌ β β request.allowPrivateNetwork = true (propagated correctly) β β β β β βΌ β β resolveProviderRequestPolicyConfig() reads from request object β β β β β βΌ β β Audio transcription succeeds on private IP endpoint β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β BROKEN BEHAVIOR (v2026.4.14) β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ β models.providers.openai.request.allowPrivateNetwork = true β β β β β βββββββββββββββββββββ΄ββββββββββββββββββββ β β βΌ βΌ β β [BUG 1] resolveProviderExecutionContext() Provider config β β NEVER includes provider config β allowPrivateNetwork = undefined β β β β β βΌ β β mergeProviderRequestOverrides() produces request without β β allowPrivateNetwork field β β β β β βΌ β β [BUG 2] resolveProviderRequestPolicyConfig() β β only checks params.allowPrivateNetwork (not params.request) β β β allowPrivateNetwork = false (default) β β β β β βΌ β β SS