# Model-controlled argument redirects credentials

LLM-supplied host, URL, proxy or disable flags reaching SDK options or trust decisions

_Area: AI and LLM app security. Seen in 3 disclosed reports; latest 2026-08-19. Updated 2026-11-08._

## How it works
A tool wrapper treats the model as a trusted caller. It takes arguments the model produced and spreads them into a third-party SDK's options, or reads them to decide a security control. The assumption that breaks: the model is untrusted, so any field it controls is attacker input. When that field is `host`, `baseURL`, `proxy`, `rawProxy`, `insecure`, or a `dangerouslyDisable*` flag, the model can redirect where server-held credentials go or turn off a guard. The credential (a PAT, API key, session token) is attached by the SDK to whatever endpoint the options name, so it leaves for an attacker endpoint [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-2xhg-73j7-rrgx.md). The same shape applies to egress allowlists: a model-restricted URL list that includes domains an attacker can host on and read logs from becomes an exfiltration channel [E2](https://bugbountylibrary.com/r/blog%3Aembracethered-com-blog-posts-2025-chatgpt-chat-history-data-exfiltration.md).

## Where it shows up
- Tool input schemas (Zod, JSON schema) containing `host`, `baseURL`, `proxy`, `rawProxy`, `insecure`, `endpoint`, `url`, or `disable`/`force`/`skip` flags [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-2xhg-73j7-rrgx.md)[E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-m77w-p5jj-xmhg.md).
- A wrapper that extracts only `accessToken` from config and then spreads raw `...args` into SDK options [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-2xhg-73j7-rrgx.md).
- Two client-construction paths: one pins the host, another does not; the unpinned one is the bug [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-2xhg-73j7-rrgx.md).
- Security decisions (`shouldUseSandbox`) reading a model-supplied field, with a permissive default like `?? true` on the second guard [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-m77w-p5jj-xmhg.md).
- Egress allowlists naming cloud blob storage or shared hosting whose request logs the attacker can read [E2](https://bugbountylibrary.com/r/blog%3Aembracethered-com-blog-posts-2025-chatgpt-chat-history-data-exfiltration.md).

## How to review
State the invariant: no model-controlled value may reach a field that selects a destination for credentials or toggles a security control. Check every tool schema for such fields; if present, confirm the wrapper overwrites them with a server-pinned constant before calling the SDK. Confirm the guard's default is deny, not allow, and that the model cannot set it. For allowlists, confirm every entry is a domain the attacker cannot both host content on and read logs from.

## How finders spotted it
- Noticed `export_space`/`import_space` were the only tools calling the token-only `createClientConfig` instead of `createToolClient` (which pins the host), then traced `...args` through the export library into the SDK's baseURL construction [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-2xhg-73j7-rrgx.md).
- While reading the system prompt to learn how history is stored, saw all history sits in prompt context, and knowing prior allowlist bypasses were unfixed, hunted for allowlisted domains with attacker-readable logs [E2](https://bugbountylibrary.com/r/blog%3Aembracethered-com-blog-posts-2025-chatgpt-chat-history-data-exfiltration.md).
- Code review against the stated threat model (model untrusted): saw `shouldUseSandbox()` read a model input field, then traced the second guard to a permissive default [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-m77w-p5jj-xmhg.md).

## Variants seen
- Credential redirect via `host`/`proxy` spread into an SDK client [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-2xhg-73j7-rrgx.md).
- Egress allowlist bypass via attacker-controllable, log-readable domains [E2](https://bugbountylibrary.com/r/blog%3Aembracethered-com-blog-posts-2025-chatgpt-chat-history-data-exfiltration.md).
- Model-settable sandbox-disable flag with an allow-by-default guard [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-m77w-p5jj-xmhg.md).

## Impact and severity
E1: prompt injection through attacker-writable content needs no client privilege; the exfiltrated PAT gives read/write across all scoped spaces [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-2xhg-73j7-rrgx.md). E2: chat history, memories, interaction metadata and tool data leak to attacker storage [E2](https://bugbountylibrary.com/r/blog%3Aembracethered-com-blog-posts-2025-chatgpt-chat-history-data-exfiltration.md). E3: prompt injection escalates to host-level code execution and credential theft [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-m77w-p5jj-xmhg.md). Severity rises with credential scope and reach beyond the first system.

## Seen in real software
Open-source packages and projects, and products, where this pattern was found. If the target runs one, compare the version it runs with the fix.
- **@contentful/mcp-server (npm)** < 1.7.19, fixed in 1.7.19: Contentful MCP Server: export_space/import_space tools pass LLM-controlled `host`/`proxy` args to CMA client, redirectin (CVE-2026-53957). Report: https://bugbountylibrary.com/r/ghsa%3AGHSA-2xhg-73j7-rrgx.md. Fix: https://github.com/contentful/contentful-mcp-server/commit/fa7477ee48515f4248bc91a025eab0ca83423fe0
- **openclaude (npm)** < 0.5.1, fixed in 0.5.1: OpenClaude Sandbox Bypass via Model-Controlled `dangerouslyDisableSandbox` Input (CVE-2026-42074). Report: https://bugbountylibrary.com/r/ghsa%3AGHSA-m77w-p5jj-xmhg.md. Fix: https://github.com/Gitlawb/openclaude/commit/aab489055c53dd64369414116fe93226d2656273

## Evidence
- E1: https://bugbountylibrary.com/r/ghsa%3AGHSA-2xhg-73j7-rrgx.md
- E2: https://bugbountylibrary.com/r/blog%3Aembracethered-com-blog-posts-2025-chatgpt-chat-history-data-exfiltration.md
- E3: https://bugbountylibrary.com/r/ghsa%3AGHSA-m77w-p5jj-xmhg.md
