CVE-2026-114108
HKUDS Vibe-Trading before 0.1.7 Missing Authentication in FastAPI Server Enabling RCE
HKUDS Vibe-Trading from 0.1.0 before 0.1.7 contains a missing authentication vulnerability that allows unauthenticated attackers to access the FastAPI surface because require_auth() returns early when API_AUTH_KEY is unset. Attackers can post messages to /sessions/{id}/messages to trigger root shell commands via BashTool, upload .py or .sh files via /upload, read session histories, and obtain partial API keys.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- High
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
9.3
HKUDS Vibe-Trading before 0.1.7 Missing Authentication in FastAPI Server Enabling RCE
HKUDS Vibe-Trading from 0.1.0 before 0.1.7 contains a missing authentication vulnerability that allows unauthenticated attackers to access the FastAPI surface because require_auth() returns early when API_AUTH_KEY is unset. Attackers can post messages to /sessions/{id}/messages to trigger root shell commands via BashTool, upload .py or .sh files via /upload, read session histories, and obtain partial API keys.
- Record
CVE-2026-114108- CVSS 4.0
- 9.3 Critical
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N - CVSS 3.1
- 9.8 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-306
- Updated
- 2026-11-02
EUVDEUVD-2026-106911
9.3
HKUDS Vibe-Trading from 0.1.0 before 0.1.7 contains a missing authentication vulnerability that allows unauthenticated attackers to access the FastAPI surface because require_auth() returns early when API_AUTH_KEY is unset. Attackers can post messages to /sessions/{id}/messages to trigger root shell commands via BashTool, upload .py or .sh files via /upload, read session histories, and obtain partial API keys.
- Record
EUVD-2026-106911- CVSS 4.0
- 9.3 Critical
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-6gpw-8ggq-h6c8
9.3
HKUDS Vibe-Trading from 0.1.0 before 0.1.7 contains a missing authentication vulnerability that...
HKUDS Vibe-Trading from 0.1.0 before 0.1.7 contains a missing authentication vulnerability that allows unauthenticated attackers to access the FastAPI surface because require_auth() returns early when API_AUTH_KEY is unset. Attackers can post messages to /sessions/{id}/messages to trigger root shell commands via BashTool, upload .py or .sh files via /upload, read session histories, and obtain partial API keys.
- Record
GHSA-6gpw-8ggq-h6c8- CVSS 4.0
- 9.3 Critical
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 9.8 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-306
- Updated
- 2026-11-02
GitHub AdvisoriesGHSA-v2f8-6655-7grj
10.0
Vibe-Trading FastAPI endpoints permit unauthenticated access, file upload, and an RCE chain
Summary:
5 findings — unauthenticated full-API exposure (F1, lead Critical), read-side authorization gap that persists even with API_AUTH_KEY set (F2), unauthenticated file write of .py/.sh/.yaml to a server-returned path (F3), default-permissive CORS that combines with a loopback-only check to grant any browser page on whitelisted localhost ports credentialed cross-origin access (F-A4), and partial API-key disclosure via _mask_secret() (F-A5).
Shared baseline (applies to all 5 findings)
The shipped agent/.env.example line 112 ships # API_AUTH_KEY= commented out. require_auth() at agent/api_server.py line 303 executes if not api_key: return and returns None immediately when API_AUTH_KEY is unset, so every endpoint decorated with dependencies=[Depends(require_auth)] operates as unauthenticated. The shipped Dockerfile does not contain a USER directive, so the FastAPI process runs as uid=0(root) inside the container (verified: docker exec id returns uid=0(root) gid=0(root)). The docker-compose.yml binds 0.0.0.0:8899 with no network restriction.
The only operator action required beyond a clean install is supplying a working LLM API key so the agent loop can complete its tool-call round trip — this is the normal first step to make the agent functional, not an additional security opt-in. F-A4 and F-A5 do not require an LLM key (see per-finding notes); F1 and F3 do not require an LLM key for the unauth surface itself, only for the chained RCE demonstration in F1.
Reproducer environment (common)
git clone https://github.com/HKUDS/Vibe-Trading.git
cd Vibe-Trading
git checkout 7452610113a75529b5d55fd2217bb17f7bec66f7 # v0.1.6 + 1 frontend fix; same vuln state as v0.1.6
cp agent/.env.example agent/.env
# (For F1 chained demo only:) edit agent/.env to set OPENROUTER_API_KEY=<real key>
docker compose up -d
# port 8899 is now reachable; HOST below is the docker host's IP from the attacker's perspective
Note on the
HOSTplaceholder used throughout the per-finding "Steps to observe" blocks below: replaceHOSTwith the address you reach the docker host on — typicallylocalhost(or127.0.0.1) if you are running the reproducer on the same machine as the container. Allcurlcommands below assume this substitution.
Finding 1 — Critical: Unauthenticated network client reaches shell execution via POST /sessions/{id}/messages
- Severity: Critical
- CVSS v3.1: 9.8 —
AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H - CVSS v4.0: 10.0 —
AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H - CWE: CWE-306 (Missing Authentication for Critical Function); chains into CWE-78 (Group B, F6)
Affected files:
agent/api_server.py:303—if not api_key: returnearly return inrequire_auth()agent/api_server.py:736—@app.post("/sessions/{session_id}/messages", dependencies=[Depends(require_auth)])(the dependency is a no-op whenAPI_AUTH_KEYis unset)agent/src/tools/bash_tool.py:44-46—subprocess.run(command, shell=True, cwd=cwd)with command read fromkwargs['command'](full bug detail tracked in GHSA-2 / Group B / F6)
Intent vs actual: The session API is intended to serve authenticated users only. When API_AUTH_KEY is unset, require_auth() returns None immediately and dependencies=[Depends(require_auth)] becomes a no-op. Any anonymous TCP client to port 8899 can therefore create a session, post a message, and receive the LLM agent's response. The LLM ReAct agent — given a natural-language request to run a command — selects BashTool from the auto-discovered registry, which calls subprocess.run(command, shell=True) with the LLM-emitted string. The container has no USER directive, so the resulting process runs as uid=0(root).
Steps to observe:
- Start the server per the shared reproducer above (with a working
OPENROUTER_API_KEYset inagent/.env). Confirm `curl -fs…
- Record
GHSA-v2f8-6655-7grj- CVSS 3.1
- 10.0 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H - Weakness
- CWE-200, CWE-306, CWE-434, CWE-862, CWE-942
- Updated
- 2026-11-02
NVD
9.3
HKUDS Vibe-Trading from 0.1.0 before 0.1.7 contains a missing authentication vulnerability that allows unauthenticated attackers to access the FastAPI surface because require_auth() returns early when API_AUTH_KEY is unset. Attackers can post messages to /sessions/{id}/messages to trigger root shell commands via BashTool, upload .py or .sh files via /upload, read session histories, and obtain partial API keys.
- Record
CVE-2026-114108- CVSS 4.0
- 9.3 Critical
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 9.8 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-306
- Updated
- 2026-11-02
OSV
9.3
HKUDS Vibe-Trading before 0.1.7 Missing Authentication in FastAPI Server Enabling RCE
HKUDS Vibe-Trading from 0.1.0 before 0.1.7 contains a missing authentication vulnerability that allows unauthenticated attackers to access the FastAPI surface because require_auth() returns early when API_AUTH_KEY is unset. Attackers can post messages to /sessions/{id}/messages to trigger root shell commands via BashTool, upload .py or .sh files via /upload, read session histories, and obtain partial API keys.
- Record
CVE-2026-114108- CVSS 4.0
- 9.3 Critical
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-306
- Updated
- 2026-11-04
OSVGHSA-v2f8-6655-7grj
10.0
Vibe-Trading FastAPI endpoints permit unauthenticated access, file upload, and an RCE chain
Summary:
5 findings — unauthenticated full-API exposure (F1, lead Critical), read-side authorization gap that persists even with API_AUTH_KEY set (F2), unauthenticated file write of .py/.sh/.yaml to a server-returned path (F3), default-permissive CORS that combines with a loopback-only check to grant any browser page on whitelisted localhost ports credentialed cross-origin access (F-A4), and partial API-key disclosure via _mask_secret() (F-A5).
Shared baseline (applies to all 5 findings)
The shipped agent/.env.example line 112 ships # API_AUTH_KEY= commented out. require_auth() at agent/api_server.py line 303 executes if not api_key: return and returns None immediately when API_AUTH_KEY is unset, so every endpoint decorated with dependencies=[Depends(require_auth)] operates as unauthenticated. The shipped Dockerfile does not contain a USER directive, so the FastAPI process runs as uid=0(root) inside the container (verified: docker exec id returns uid=0(root) gid=0(root)). The docker-compose.yml binds 0.0.0.0:8899 with no network restriction.
The only operator action required beyond a clean install is supplying a working LLM API key so the agent loop can complete its tool-call round trip — this is the normal first step to make the agent functional, not an additional security opt-in. F-A4 and F-A5 do not require an LLM key (see per-finding notes); F1 and F3 do not require an LLM key for the unauth surface itself, only for the chained RCE demonstration in F1.
Reproducer environment (common)
git clone https://github.com/HKUDS/Vibe-Trading.git
cd Vibe-Trading
git checkout 7452610113a75529b5d55fd2217bb17f7bec66f7 # v0.1.6 + 1 frontend fix; same vuln state as v0.1.6
cp agent/.env.example agent/.env
# (For F1 chained demo only:) edit agent/.env to set OPENROUTER_API_KEY=<real key>
docker compose up -d
# port 8899 is now reachable; HOST below is the docker host's IP from the attacker's perspective
Note on the
HOSTplaceholder used throughout the per-finding "Steps to observe" blocks below: replaceHOSTwith the address you reach the docker host on — typicallylocalhost(or127.0.0.1) if you are running the reproducer on the same machine as the container. Allcurlcommands below assume this substitution.
Finding 1 — Critical: Unauthenticated network client reaches shell execution via POST /sessions/{id}/messages
- Severity: Critical
- CVSS v3.1: 9.8 —
AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H - CVSS v4.0: 10.0 —
AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H - CWE: CWE-306 (Missing Authentication for Critical Function); chains into CWE-78 (Group B, F6)
Affected files:
agent/api_server.py:303—if not api_key: returnearly return inrequire_auth()agent/api_server.py:736—@app.post("/sessions/{session_id}/messages", dependencies=[Depends(require_auth)])(the dependency is a no-op whenAPI_AUTH_KEYis unset)agent/src/tools/bash_tool.py:44-46—subprocess.run(command, shell=True, cwd=cwd)with command read fromkwargs['command'](full bug detail tracked in GHSA-2 / Group B / F6)
Intent vs actual: The session API is intended to serve authenticated users only. When API_AUTH_KEY is unset, require_auth() returns None immediately and dependencies=[Depends(require_auth)] becomes a no-op. Any anonymous TCP client to port 8899 can therefore create a session, post a message, and receive the LLM agent's response. The LLM ReAct agent — given a natural-language request to run a command — selects BashTool from the auto-discovered registry, which calls subprocess.run(command, shell=True) with the LLM-emitted string. The container has no USER directive, so the resulting process runs as uid=0(root).
Steps to observe:
- Start the server per the shared reproducer above (with a working
OPENROUTER_API_KEYset inagent/.env). Confirm `curl -fs…
- Record
GHSA-v2f8-6655-7grj- CVSS 3.1
- 10.0 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H - Weakness
- CWE-200, CWE-306, CWE-434, CWE-862, CWE-942
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
vibe-trading-aiPyPI |
0.1.0 up to 0.1.7 | 0.1.7 |
vibe-trading-aiPyPI |
0.1.0 up to 0.1.7, plus listed versions 0.1.10.1.20.1.30.1.40.1.50.1.6 |
0.1.7 |
History
| Recorded | Changed | Sources |
|---|---|---|
| facts | OSV | |
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-114108 is a critical vulnerability (CVSS 9.3) in Hkuds Vibe-trading, published October 2, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.53%, the 44th percentile. Fixed in vibe-trading-ai 0.1.7.
References
github.com/HKUDS/Vibe-Trading/security/advisories/GHSA-v2f8-6655-7grj
vulncheck.com/advisories/hkuds-vibe-trading-before-0.1.7-missing-authentication-in-fastapi-server-enabling-rce
nvd.nist.gov/vuln/detail/CVE-2026-114108
github.com/advisories/GHSA-6gpw-8ggq-h6c8
github.com/HKUDS/Vibe-Trading/commit/9454d4a27a763b80e1d6eb5763b86c88e9e4e714
github.com/HKUDS/Vibe-Trading/releases/tag/v0.1.7
github.com/advisories/GHSA-v2f8-6655-7grj
github.com/CVEProject/cvelistV5/tree/main/cves/2026/114xxx/CVE-2026-114108.json
github.com/HKUDS/Vibe-Trading
Left out here: the rest of 2 source descriptions. The JSON record has them.