Skip to content

CVE-2026-58169: Verified Reproduction

CVE-2026-58169: Vibe-Trading DNS rebinding authentication bypass leading to RCE

CVE-2026-58169 is verified against the affected target. Vulnerability class: RCE. This high reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00254.

REPRO-2026-00254 RCE Jul 6, 2026 CVE entry .txt
Severity
HIGH
CVSS
7.5
Confidence
HIGH
Reproduced in
18m 8s
Tool calls
239
Spend
$3.88
01 · Overview

What Is CVE-2026-58169?

CVE-2026-58169 is a high-severity DNS rebinding authentication bypass (CWE-346) in Vibe-Trading that lets an unauthenticated attacker bypass API authentication and reach a remote code execution primitive. Pruva reproduced it (reproduction REPRO-2026-00254).

02 · Severity & CVSS

CVE-2026-58169 Severity & CVSS Score

CVE-2026-58169 is rated high severity, with a CVSS base score of 7.5 out of 10.

HIGH threat level
7.5 / 10 CVSS base
Weakness CWE-346 (Origin Validation Error)

High — serious impact or readily exploitable. Prioritize remediation.

How to Reproduce CVE-2026-58169

$ pruva-verify REPRO-2026-00254
or curl -O https://www.pruva.dev/api/v1/reproductions/REPRO-2026-00254/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh
Run in a VM or disposable container. This exploits a real vulnerability.
06 · Proof of Reproduction

Proof of Reproduction for CVE-2026-58169

Remote code execution — reproduced
  • reached the target end-to-end
  • full exploit chain demonstrated
  • on the real production code path
  • high confidence
  • the upstream fix blocks the same trigger
Trigger

DNS-rebound Host header (rebind.attacker.test:8899) with no bearer token, sent via curl --resolve to 127.0.0.1

Attack chain
  1. DNS rebinding
  2. loopback TCP peer
  3. _is_local_client() bypasses API_AUTH_KEY
  4. _shell_tools_enabled_for_request() enables bash tool
  5. POST /sessions/{id}/messages
  6. BashTool subprocess.run(shell=True)
  7. RCE
How the agent worked 541 events · 239 tool calls · 18 min
18 minDuration
239Tool calls
123Reasoning steps
541Events
2Dead-ends
Agent activity over 18 min
Support
18
Repro
300
Judge
35
Variant
184
0:0018:08

Root Cause and Exploit Chain for CVE-2026-58169

Versions: Vibe-Trading < 0.1.10 (confirmed on v0.1.9, commit 8cebccb9b301f962d11bf0fa8c6be9bf7d7e12f2)Fixed: v0.1.10 (commit 54f944743efee7b9cbaaeafb5966c583d0d4ac66), via PR #242 (6e06017) — adds _reject_untrusted_loopback_host middleware

Vibe-Trading before v0.1.10 contains a DNS rebinding authentication bypass vulnerability (CWE-346 Origin Validation Error). The FastAPI API server (agent/api_server.py) binds to 0.0.0.0 by default and treats any TCP connection from a loopback peer address (127.0.0.1, ::1, localhost) as a trusted local/dev-mode caller, bypassing API_AUTH_KEY bearer-token authentication entirely. Because the server performs no Host header validation on loopback-trusted requests, an attacker can use DNS rebinding to make a victim's browser issue same-origin JSON requests to the local API with an attacker-controlled Host header and no bearer token. The loopback peer IP causes _is_local_client() to return True, so _validate_api_auth() skips authentication. Furthermore, _shell_tools_enabled_for_request() returns True for loopback clients, enabling the bash tool in the agent's tool registry. The attacker can then send a message to a session that triggers the BashTool, which executes subprocess.run(command, shell=True) — achieving remote code execution as the API process user. The attacker can also overwrite LLM and data-source settings to exfiltrate credentials.

  • Package/component affected: HKUDS/Vibe-Tradingagent/api_server.py (loopback trust/auth boundary, Host-header validation), agent/src/tools/bash_tool.py (BashTool RCE primitive), agent/src/tools/__init__.py (shell tool gating)
  • Affected versions: Vibe-Trading < 0.1.10 (confirmed on v0.1.9, commit 8cebccb9b301f962d11bf0fa8c6be9bf7d7e12f2)
  • Fixed version: v0.1.10 (commit 54f944743efee7b9cbaaeafb5966c583d0d4ac66), via PR #242 (6e06017) — adds _reject_untrusted_loopback_host middleware
  • Risk level: High (CVSS 7.7 / 8.1)
  • Consequences: Unauthenticated remote code execution as the API process user; unauthorized access to privileged control-plane endpoints (/live/runner/start, /swarm/runs, /sessions/{id}/messages); credential exfiltration via settings overwrite (/settings/llm, /settings/data-sources)

Impact Parity

  • Disclosed/claimed maximum impact: DNS rebinding authentication bypass leading to remote code execution (code_execution) and credential exfiltration
  • Reproduced impact from this run: Full chain demonstrated — DNS rebinding → auth bypass → shell tools enabled → BashTool executes arbitrary shell command as API process user (uid=1000(vscode)). The proof file /tmp/vibe_trading_rce_proof_*.txt was created with RCE_CONFIRMED. The agent trace shows tool_call: bash with exit_code: 0 and stdout: "uid=1000(vscode)...".
  • Parity: full
  • Not demonstrated: The reproduction used a mock LLM server (simulating an attacker-controlled LLM endpoint) to instruct the agent to invoke the bash tool. In a real attack, the attacker would either poison the LLM settings (via the auth-bypassed /settings/llm PUT) to point the agent at an attacker-controlled LLM, or craft a user message that persuades the agent to run a shell command. The code-execution primitive (BashTool with subprocess.run(shell=True)) is the same either way.

Root Cause

The root cause is a loopback peer IP trust without Host header validation:

  1. _is_local_client(request) (line 668) checks only request.client.host (the TCP peer address). If it is 127.0.0.1, ::1, localhost, or a trusted Docker gateway, it returns True.

  2. _validate_api_auth() (line 645): when API_AUTH_KEY is not configured (dev mode), a loopback client is allowed without any token. When API_AUTH_KEY IS configured, the loopback shortcut is not used — but in dev mode (the default), the bypass is complete.

  3. _shell_tools_enabled_for_request(request) (line 727): returns _is_local_client(request) or _env_shell_tools_enabled(). For loopback clients, this is True, enabling the bash and background_run tools in the agent registry.

  4. No Host header validation existed — a loopback request carrying Host: attacker.example:8899 was trusted as local. DNS rebinding makes a browser send exactly such a request: the attacker's domain resolves to 127.0.0.1, the browser connects from loopback, and sends Host: attacker.example:8899 (the original hostname) with no bearer token.

  5. The BashTool.execute() (line 38 of bash_tool.py) calls subprocess.run(command, shell=True, cwd=cwd, ...) — arbitrary command execution.

Fix (PR #242, commit 6e06017): Added _reject_untrusted_loopback_host middleware that rejects loopback requests carrying an untrusted Host header with HTTP 403 ("Untrusted local API host") before route handlers are reached. Accepted loopback Host values: localhost, 127.0.0.1, ::1, [::1], testserver, plus any configured via API_ALLOWED_HOSTS. Remote clients remain governed by bearer-token auth. Normal loopback dev-mode requests with Host: 127.0.0.1:port continue to work (no regression).

Related fixes in the same v0.1.10 cycle:

  • PR #243 (7eb8dea): require explicit opt-in (VIBE_TRADING_ENABLE_SHELL_TOOLS) for agent shell tools — closes the BashTool exposure even if the Host gate is bypassed
  • PR #245 (b608fc5): require bearer token for settings WRITE endpoints — closes the credential exfiltration path

Reproduction Steps

  1. Script: bundle/repro/reproduction_steps.sh — self-contained, run with PRUVA_ROOT=<bundle_dir> bash bundle/repro/reproduction_steps.sh
  2. What the script does:
    • Installs Python dependencies (fastapi, uvicorn, langchain, dnslib, etc.)
    • Clones/reuses the Vibe-Trading repo from the project cache
    • Starts a DNS rebinding server (dns_rebind_server.py) that resolves rebind.attacker.test to 127.0.0.1
    • Proves the DNS rebinding with a real DNS A-record query → 127.0.0.1
    • Starts a mock OpenAI-compatible LLM server (mock_llm_server.py) that returns a bash tool-call instructing the agent to execute id; whoami; echo RCE_CONFIRMED > /tmp/...
    • Phase 1 (vulnerable v0.1.9): Starts the real Vibe-Trading API server (bound to 0.0.0.0:8899, dev mode, mock LLM). Uses curl --resolve rebind.attacker.test:8899:127.0.0.1 to send DNS-rebound HTTP requests with no bearer token:
      • POST /sessions → HTTP 201 (auth bypassed, session created)
      • POST /sessions/{id}/messages → triggers the agent loop → BashTool executes the attacker's command → RCE proof file created
      • PUT /settings/llm → auth-bypassed settings write (credential exfiltration path)
    • Phase 2 (fixed v0.1.10): Same DNS-rebound requests → HTTP 403 ("Untrusted local API host"). Normal loopback with Host: 127.0.0.1:8899 → HTTP 201 (no regression).
    • Writes validation_verdict.json and runtime_manifest.json
  3. Expected evidence:
    • logs/dns_rebind_proof.txt: DNS_A:rebind.attacker.test:127.0.0.1
    • logs/vuln_create_session.txt: HTTP 201 with session_id (no auth)
    • logs/vuln_rce_proof.txt: RCE_CONFIRMED
    • logs/vuln_trace.jsonl: tool_call: bash with exit_code: 0, stdout: "uid=1000(vscode)..."
    • logs/fixed_create_session.txt: HTTP 403 {"detail":"Untrusted local API host"}
    • logs/fixed_normal_loopback.txt: HTTP 201 (no regression)

Evidence

All artifacts are under bundle/logs/ and bundle/repro/:

Artifact Description
logs/reproduction_steps.log Full script execution log
logs/dns_rebind_proof.txt DNS A-record query proving rebind.attacker.test → 127.0.0.1
logs/vuln_create_session.txt Vulnerable: POST /sessions → HTTP 201 (auth bypass)
logs/vuln_send_message.txt Vulnerable: POST /sessions/{id}/messages → HTTP 200
logs/vuln_rce_proof.txt RCE proof file: RCE_CONFIRMED
logs/vuln_trace.jsonl Agent trace showing tool_call: bash, tool_result: exit_code 0, uid=1000(vscode)
logs/vuln_session_messages.json Session message history (user + assistant reply)
logs/vuln_settings_write.txt Vulnerable: PUT /settings/llm → HTTP 422 (auth bypassed, validation error)
logs/fixed_create_session.txt Fixed: POST /sessions → HTTP 403 "Untrusted local API host"
logs/fixed_normal_loopback.txt Fixed: normal loopback → HTTP 201 (no regression)
logs/fixed_settings_write.txt Fixed: PUT /settings/llm → HTTP 403
logs/api_server_vulnerable.log Vulnerable API server log
logs/api_server_fixed.log Fixed API server log
logs/mock_llm_server.log Mock LLM server log
logs/dns_rebind_server.log DNS rebinding server log

Key trace excerpt (vuln_trace.jsonl):

{"type": "tool_call", "iter": 1, "tool": "bash", "args": {"command": "id; whoami; echo RCE_CONFIRMED > /tmp/vibe_trading_rce_proof_49561.txt", "run_dir": "..."}}
{"type": "tool_result", "iter": 1, "tool": "bash", "status": "ok", "elapsed_ms": 4, "preview": "{\"status\": \"ok\", \"exit_code\": 0, \"stdout\": \"uid=1000(vscode) gid=1000(vscode) groups=1000(vscode),969(969)\\nvscode\\n\", \"stderr\": \"id: cannot find name for group ID 969\\n\"}"}

Vulnerable vs fixed comparison:

Request v0.1.9 (vulnerable) v0.1.10 (fixed)
POST /sessions (DNS-rebound, no auth) 201 (auth bypassed) 403 ("Untrusted local API host")
POST /sessions/{id}/messages (DNS-rebound) 200 → BashTool RCE 403
PUT /settings/llm (DNS-rebound) 422 (auth bypassed) 403
POST /sessions (normal loopback Host: 127.0.0.1) 201 201 (no regression)

Environment:

  • Python 3.14.4, FastAPI + uvicorn, langchain-openai (ChatOpenAI)
  • Vibe-Trading v0.1.9 (vulnerable) / v0.1.10 (fixed)
  • API server bound to 0.0.0.0:8899 (default), dev mode (no API_AUTH_KEY)
  • DNS rebinding server: dnslib UDP server on 127.0.0.1:5353
  • Mock LLM: http.server on 127.0.0.1:9099 returning OpenAI-compatible tool-call responses

Recommendations / Next Steps

  1. Upgrade to v0.1.10 or later — the _reject_untrusted_loopback_host middleware (PR #242) blocks DNS-rebinding Host headers on loopback peers with HTTP 403.
  2. Set API_AUTH_KEY in any deployment exposed beyond a single-user localhost — this forces bearer-token auth even for loopback clients when configured, removing the dev-mode bypass.
  3. Set VIBE_TRADING_ENABLE_SHELL_TOOLS=1 only when explicitly needed — PR #243 requires explicit opt-in for the BashTool; without it, the RCE primitive is unavailable even if auth is bypassed.
  4. Bind to 127.0.0.1 instead of 0.0.0.0 when the API is not meant to be network-accessible.
  5. Configure API_ALLOWED_HOSTS if fronting the local API with a specific loopback hostname.
  6. Testing: run the security regression tests: PYTHONPATH=agent python -m pytest agent/tests/test_security_auth_api.py -q

Additional Notes

  • Idempotency: The script was run twice consecutively; both runs produced identical results (HTTP 201 + RCE on vulnerable, HTTP 403 on fixed). The script cleans up all background processes on exit and uses a PID-suffixed proof file to avoid collisions.
  • Mock LLM justification: The reproduction uses a mock OpenAI-compatible LLM server that returns a bash tool-call. This simulates the attack scenario where the attacker either (a) poisons the LLM settings via the auth-bypassed /settings/llm PUT to point at an attacker-controlled LLM, or (b) sends a user message that the agent's LLM responds to with a bash tool-call. The BashTool's subprocess.run(shell=True) is the actual RCE primitive in both cases — the mock LLM merely drives the agent loop to reach it.
  • The PUT /settings/llm returned 422 (not 200) on the vulnerable version because the request body did not match the full Pydantic model schema, but the important point is that the request passed authentication (no 401/403) — the auth bypass is confirmed. On the fixed version, the same request returns 403 at the Host-gate middleware before reaching the route handler.
  • CORS does not defend against DNS rebinding — after rebinding, the attacker's hostname becomes the browser's same origin, so credentialed CORS requests are sent without cross-origin restrictions.

CVE-2026-58169 Reproduction Transcript

The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.

Full session Replay every step — scrub the timeline or play it back.

Event 1/40
0:001:01
0:00
session startedaccounts/fireworks/routers/glm-5p2-fast · CVE-2026-58169 · REPRO-20
0:02
0:05
web search
0:07
web search
0:09
0:11
web search
0:13
web search
0:16
0:17
0:18
0:39
0:39
extract_facts
no facts extracted
0:41
0:41
0:41
supportrepro
0:43
0:43
0:43
0:44
0:44
0:44
0:47
0:47
0:48
web search
0:51
0:51
0:52
0:56
0:59
$cd /data/pruva/project-cache/b9cd83d4-18cf-44e8-8cea-3367d315f18e && git clone --quiet https://github.com/HKUDS/Vibe-Trading.git repo 2>&1 | tail -5; echo "EXIT: $?"; ls repo 2>/dev/null | head
2.5s
EXIT: 0
AGENT_CONTRIBUTOR_GUIDE.md
CHANGELOG.md
CODE_OF_CONDUCT.md
CONTRIBUTING.md
Dockerfile
LICENSE
MANIFEST.in
1:01
08 · How to Fix

How to Fix CVE-2026-58169

Coming soon

Step-by-step mitigation and hardening guidance for CVE-2026-58169 — configuration checks, workarounds where no patch exists, and how to verify you're protected — is on the way.

10 · FAQ

FAQ: CVE-2026-58169

How does the CVE-2026-58169 exploit chain reach RCE?

Once the DNS-rebinding request lands as a trusted loopback client, _shell_tools_enabled_for_request() also returns True for loopback clients, enabling the agent's bash tool. The attacker sends a message to a session that triggers BashTool, which runs subprocess.run(command, shell=True), giving remote code execution as the API process user; the attacker can also overwrite LLM and data-source settings to exfiltrate credentials.

Which Vibe-Trading versions are affected by CVE-2026-58169, and where is it fixed?

Vibe-Trading versions before 0.1.10 are affected (confirmed on v0.1.9). It is fixed in 0.1.10.

How severe is CVE-2026-58169?

It is rated high severity: an unauthenticated attacker who can lure a victim to a malicious page can bypass authentication via DNS rebinding and achieve remote code execution as the API process user.

How can I reproduce CVE-2026-58169?

Download the verified script from this page and run it in an isolated environment against Vibe-Trading before 0.1.10. It sets up a DNS rebinding scenario targeting the FastAPI server, sends requests that satisfy the loopback-trust check without a bearer token, and then invokes the bash tool to demonstrate command execution on the vulnerable build.
11 · References

References for CVE-2026-58169

Authoritative sources for CVE-2026-58169 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.