litellm - ✅(Solved) Fix [Bug]: /user/update stores password as plaintext instead of hashing it [1 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
BerriAI/litellm#25328Fetched 2026-04-09 07:52:46
View on GitHub
Comments
0
Participants
1
Timeline
2
Reactions
0
Participants
Timeline (top)
cross-referenced ×1referenced ×1

PR fix notes

PR #25401: fix: store hashed password on /user/new when password field is provided

Description (problem / solution / changelog)

What's the problem?

Fixes #25328.

Two bugs prevented the password field from being stored when creating a new user via POST /user/new:

  1. NewUserRequest had no password field, so Pydantic discarded it before the handler ran.
  2. generate_key_helper_fn does not accept password and its internal user_data dict does not include it, so even if the field existed it would never reach the database.

What's the fix?

  • Added password: Optional[str] = None to NewUserRequest with an 8-character minimum validation rule (Pydantic field_validator)
  • In new_user(): hash the password via the existing _hash_password_in_dict(), pop it from data_json before forwarding to generate_key_helper_fn, then persist it via a targeted litellm_usertable.update() after the user row is created
  • Raise HTTP 500 (instead of silently dropping the password) if user_id is not returned after creation

Tests

  • test_new_user_password_is_hashed_and_stored — verifies password not passed to generate_key_helper_fn, stored hashed, verifiable
  • test_new_user_password_raises_if_user_id_missing — verifies HTTP 500 when user_id is absent from creation response

Checklist

  • Added tests in tests/test_litellm/
  • make test-unit passes locally

Changed files

  • litellm/proxy/_types.py (modified, +58/-48)
  • litellm/proxy/management_endpoints/internal_user_endpoints.py (modified, +38/-19)
  • tests/test_litellm/proxy/management_endpoints/test_internal_user_endpoints.py (modified, +234/-0)

Code Example

curl -X POST '/user/update' \
  -H 'Authorization: Bearer <master_key>' \
  -H 'Content-Type: application/json' \
  -d '{"user_id": "[email protected]", "password": "test1234"}'
RAW_BUFFERClick to expand / collapse

Description:

Environment:

LiteLLM version: v1.82.3 (main-stable Docker image, pulled ~2 weeks ago) Database: PostgreSQL 16 Bug Description: When setting a user password via /user/update, the password is stored as plaintext in LiteLLM_UserTable instead of being hashed.

Steps to Reproduce:

Create a user via /user/new Set password via /user/update:

curl -X POST '/user/update' \
  -H 'Authorization: Bearer <master_key>' \
  -H 'Content-Type: application/json' \
  -d '{"user_id": "[email protected]", "password": "test1234"}'

Query the database: SELECT password FROM "LiteLLM_UserTable" WHERE user_id = '[email protected]'; Result: test1234 (plaintext, not hashed) Additional Bug: /user/new with password field does not store the password at all — generate_key_helper_fn does not include password in its user_data dict.

Expected Behavior: Password should be hashed (scrypt or SHA256) before storing in the database.

Security Impact: Passwords stored in plaintext are visible to anyone with database access.

Note: It appears this was fixed in v1.83.x with the addition of _hash_password_in_dict() in _update_single_user_helper()

extent analysis

TL;DR

Upgrade to LiteLLM version v1.83.x to utilize the fixed password hashing functionality.

Guidance

  • Review the changes introduced in v1.83.x, specifically the _hash_password_in_dict() function in _update_single_user_helper(), to understand the fix.
  • Verify that the password is hashed correctly by querying the database after updating a user's password via /user/update.
  • Check the generate_key_helper_fn function to ensure it includes the password in the user_data dict when creating a new user via /user/new.
  • Test the password hashing functionality with different password update scenarios to ensure it works as expected.

Example

No code snippet is provided as the issue implies the fix is available in a newer version.

Notes

The provided information suggests that the issue is resolved in v1.83.x, but it does not provide details on how to manually implement the fix in v1.82.3. Upgrading to the fixed version is the recommended course of action.

Recommendation

Upgrade to fixed version v1.83.x, as it includes the necessary changes to hash passwords correctly, addressing the security vulnerability.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING