Skip to content

Secure Outbound Transport Threat Model ​

This document outlines the security posture, control-status mapping, and STRIDE-style threat matrix for the planned built-in outbound transport in MultiModel Dev OS.


1. Gateway Security & Outbound Transport Control Posture ​

Every security control across contract, validator, gate, executor, transport, and runtime layers is classified below using canonical status terms:

ControlLayerCurrent StatusDescription
URL Syntax ValidationValidator Layervalidator-enforcedValidates strict HTTPS scheme, parses valid URL format, and rejects invalid structures in validateProviderEndpoint().
Trusted Endpoint BindingGate Layergate-enforcedAsserts that execution_request.endpoint matches the provider's registered endpoint metadata before execution.
Hostname AllowlistingGate / Executor Layernot implementedHostname allowlisting per provider is planned; currently endpoints rely on URL syntax and endpoint binding.
DNS ResolutionTransport LayerplannedAsynchronous resolution of hostnames to IPv4/IPv6 addresses via node:dns/promises.
IP Classification (DNS-Level)Transport Layernot implementedPre-connection classification and fail-closed rejection of private, loopback, link-local, multicast, CGNAT, and reserved IP ranges.
Literal Private IP CheckValidator Layervalidator-enforcedString-based parsing rejects literal IP strings (e.g. 127.0.0.1, 10.0.0.1, 169.254.169.254); does not protect against domain-name DNS resolution to private IPs.
Connection-Time Address PinningTransport LayerplannedConnecting directly to pre-resolved and validated IP address using custom lookup in node:https or direct socket creation in node:net / node:tls.
TLS Certificate VerificationTransport Layernot implementedBuilt-in native transport with rejectUnauthorized: true and SNI preservation is planned for Sprint F2. Injected test transports handle TLS independently.
Redirect Handling (Contract)Gate / Validatorvalidator-enforcedValidator enforces follow_redirects: false; gate denies policy with follow_redirects: true.
Redirect Rejection (Transport)Transport LayerplannedBuilt-in transport strictly rejects HTTP 3xx responses without following redirect locations.
Request/Response Byte LimitsExecutor Layerexecutor-enforcedEnforces max_request_bytes and max_response_bytes at payload normalization and streaming levels.
Credential Header BoundaryTransport Layernot implementedConstructing Authorization: Bearer <secret> header exclusively inside transport using ResolvedCredential.withSecret() is planned for Sprint F2.
Timeout & CancellationExecutor / Runtimeexecutor-enforcedLifecycle timeouts (request_timeout_ms, response_timeout_ms) and AbortSignal propagation managed by executor.
Observability RedactionObservability Layerruntime-enforcedStrips prompts, completions, credentials, and sensitive headers from event metrics and trace logs.
Injected Transport TrustRuntime Layerruntime-enforcedGoverned execution in Sprint E1/E2 functions strictly via explicitly provided in-process transport implementations.

2. STRIDE Threat Matrix ​

The expanded STRIDE threat matrix documents key security assets, threat vectors, entry points, preconditions, impacts, mitigations, residual risks, responsible sprints, and current implementation status:

AssetAttackerEntry PointPreconditionImpactPrevention StrategyDetectionResidual RiskResponsible Sprint / TestCurrent Status
Local ServicesMalicious ConfigLocal Policy / EndpointConfig specifies private IP literal (e.g. 127.0.0.1)SSRF to local serviceString-based private IP rejection in validateProviderEndpoint()Validator error logsHostname resolving to loopback bypasses string checkSprint A (tests/unit/execution-security.test.js)validator-enforced
Local Services / Cloud MetadataUntrusted DNS / AttackerHostname ResolutionHostname resolves to private/loopback/link-local IPSSRF to internal network / metadata APIPre-connection IP range classification and fail-closed rejectionTransport audit logs & IP classifier errorsCompromised local DNS server prior to lookupSprint F1 (tests/unit/transport-destination-policy.test.js)planned
DNS ResolverNetwork MitMUpstream DNSAttacker tampers with DNS responseTraffic sent to malicious IPValidate all returned DNS IPs; pin socket; require TLS cert hostname matchTLS handshake failure on host mismatchMalicious server presents valid CA cert for target domainSprint F1 / F2 (tests/unit/transport-dns.test.js)planned
IP BoundariesMalicious DNS ServerHostname ResolutionDNS returns public IP first, then private IP on connectTOCTOU / DNS rebinding SSRFPin socket connection to pre-validated IP address via custom lookupPinned IP mismatch loggingAttacker controls public IP pointing to malicious serverSprint F1 / F2 (tests/unit/transport-pinning.test.js)planned
IP ClassificationMalicious DNS ServerHostname ResolutionDNS returns array containing both public and private IP addressesSSRF if unvalidated IP chosenRequire 100% of returned addresses to pass public IP classification; fail-closed on any private answerResolution failure logResolver returns single public IP that rebindsSprint F1 (tests/unit/transport-destination-policy.test.js)planned
Private NetworkUpstream ServerHTTP 3xx RedirectServer returns 302 Found pointing to internal IPSSRF via redirectHardcode follow_redirects: false; reject 3xx responses in transportResponse status loggingApplication logic interprets 3xx as successSprint F2 (tests/unit/transport-redirect.test.js)planned
API CredentialsNetwork MitMTLS HandshakeServer presents invalid or mismatched certCredential exfiltrationrejectUnauthorized: true; strict hostname SNI matching; no custom CAsTLS verification errorsCompromised root CA on OS hostSprint F2 (tests/unit/transport-tls.test.js)planned
API CredentialsCross-Provider AttackerExecution RequestReusing OpenAI key for AnthropicCredential leakage across providersScope credential references strictly per provider IDCredential resolver checksMisconfigured provider ID in requestSprint A / C (tests/unit/gateway-credential-resolution.test.js)contract-defined
Transport HeadersMalicious Header InjectorRequest InputHeader input contains \r\nHeader injection / request smuggling / token leakageStrict CR/LF rejection; allowlist limited to Authorization, Content-Type, Accept, User-AgentHeader validation errorsProcess memory inspection by local privileged userSprint A / F2 (tests/unit/transport-headers.test.js)validator-enforced (contract); planned (transport)
HTTP ParserMalicious UpstreamHTTP ResponseUpstream sends malformed HTTP headers/chunksResponse splitting / smugglingStrict standard-library HTTP parsing; validate response status and headersTransport parse errorsNode standard-library HTTP parser bugsSprint F2 (tests/unit/transport-response.test.js)planned
Gateway MemoryUpstream ServerResponse BodyServer sends compressed / bomb payloadOut-of-memory crashEnforce max_response_bytes; accept-encoding: identity; no transparent decompressionByte budget exceeded errorsMemory pressure prior to limit breachSprint A / F2 (tests/unit/transport-limits.test.js)executor-enforced (size); planned (transport encoding)
Gateway MemoryUpstream Server / UserRequest / Response PayloadMassive JSON payload submitted or returnedRAM exhaustionBounded max_request_bytes (<= 52MB) and max_response_bytes (<= 52MB)Payload limit errorsHigh memory usage near 52MB limitSprint A / B (tests/unit/gateway-execution.test.js)executor-enforced
Gateway SocketsMalicious UpstreamSSE StreamUpstream stream stalls without closingSocket / handle leakSeparate DNS, connect, TLS, header, idle, and total execution timeout timersTimeout execution logsTimers depend on Node event loop precisionSprint E2 / F2 (tests/integration/gateway-governed-runtime-stream.test.js)executor-enforced (executor timer); planned (transport phase timers)
Gateway SocketsMalicious UpstreamResponse Headers / BodyUpstream delays response headers or body chunksSlowloris resource exhaustionresponse_timeout_ms and idle response timeoutsTimeout execution logsSlowloris sending 1 byte every 29sSprint E1 / F2 (tests/unit/gateway-execution.test.js)executor-enforced
Gateway SocketsTransport ConnectionAbort SignalSocket ignores AbortSignal triggerUnkillable socket leakImmediate socket.destroy() on abort or timeoutCancellation logAsync socket teardown delaySprint E2 / F3 (tests/integration/gateway-governed-runtime-stream.test.js)executor-enforced (executor signal); planned (transport socket destruction)
Network EndpointsEnvironment / ProxyEnvironment VariablesAmbient HTTP_PROXY or HTTPS_PROXY setRequest redirected through untrusted proxyExplicitly ignore ambient proxy environment variables in built-in transportTransport initialization checkSystem-level OS network proxy redirectionSprint F2 (tests/unit/transport-proxy.test.js)planned
Provider ExecutionMalicious In-Process CodeTransport ParameterInjected transport contains malicious socket codeArbitrary execution / network accessInjected transport is trusted in-process code; validated via validateTransport()Transport contract validationCompromised node_modules or main thread codeSprint D (tests/unit/gateway-execution.test.js)executor-enforced
Credentials / PromptsObservability CollectorEvent / Trace LogsLogger records request/response bodies or auth headersSecret / prompt leakage in logsMandatory redaction pass; redact_prompts: true; authorization headers always strippedObservability audit assertionsMemory inspection of trace bufferSprint E1 / E2 (tests/integration/gateway-governed-runtime-stream.test.js)runtime-enforced
Connection PoolUpstream ConnectionHTTP Keep-Alive PoolReusing connection across different origins/providersCredential exfiltration / cross-origin context leakDisable connection reuse across distinct providers/origins in initial transportConnection pool auditPerformance overhead of fresh TCP/TLS handshakesSprint F2 (tests/unit/transport-pooling.test.js)planned
Trust StoreLocal AttackerLocal Workspace FileAttacker modifies .ai/registries/trusted-keys.yamlAcceptance of untrusted registry manifestsCryptographic Ed25519 signature checks; file access restrictedSignature validation errorsPrivileged local user overwriting trust storeSprint A (tests/unit/registry-trust-store.test.js)validator-enforced
Local HostnameLocal AttackerOS /etc/hosts FileAttacker maps provider domain to 127.0.0.1Local MitM / credential theftPre-connection IP range classification detects 127.0.0.1 after resolution and fails closedIP classification failure logAttacker maps domain to a public IP under their controlSprint F1 (tests/unit/transport-destination-policy.test.js)planned
IP BoundariesMalicious EndpointIPv6 Address FormatEndpoint uses IPv4-mapped IPv6 (e.g. ::ffff:127.0.0.1)SSRF bypass of IPv4 checksNormalize IPv4-mapped IPv6 addresses to IPv4 and classify against IPv4 rulesIP classification failure logObscure IPv6 translation mechanismsSprint F1 (tests/unit/transport-destination-policy.test.js)planned
IP BoundariesMalicious EndpointAlternate Numeric IPEndpoint uses octal (0177.0.0.1), hex (0x7f000001), or dword (2130706433)SSRF bypass of standard decimal parserReject non-canonical IPv4 representations; enforce standard 4-octet decimal dotted notationURL / IP validation errorsAmbiguous IP parser implementationsSprint F1 (tests/unit/transport-destination-policy.test.js)planned
Hostname ParserMalicious EndpointIDN / Unicode HostnameHomograph attack / Punycode confusionHostname spoofing / SNI mismatchReject non-ASCII raw host input in first implementation; enforce strict ASCII labelsEndpoint validation errorsFuture IDN expansionSprint F1 (tests/unit/transport-destination-policy.test.js)planned

3. Honest Security Boundaries & Non-Claims ​

  1. No Built-in Provider HTTP Transport: Current v4.3 Sprint E2 runtime executes governed requests only when an explicitly constructed transport object is injected. No built-in node:https transport exists in production code today.
  2. DNS-Level SSRF Protection: Current validator checks string syntax of endpoints (rejecting literal IP strings like 127.0.0.1), but does not perform DNS resolution or IP pinning prior to connection. DNS-level SSRF protection is planned for Sprint F1/F2.
  3. Physical Secret Zeroization: In JavaScript and Node.js runtime environments, physical memory zeroization after HTTP/TLS execution cannot be guaranteed due to internal V8 string copies and garbage collection behavior. Ephemeral credential objects utilize #secret private fields and .destroy() zeroing of internal references, but V8 engine memory strings may persist until garbage collected.
  4. Ambient Environment Proxy Isolation: Built-in transport will explicitly ignore ambient process environment variables (HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, NO_PROXY) to prevent unintended request redirection.

Released under the MIT License.