Skip to content

[Infra] Merge dev branch - #27032

Merged
shin-berri merged 11 commits into
litellm_internal_stagingfrom
litellm_yj_may1_2
May 2, 2026
Merged

[Infra] Merge dev branch#27032
shin-berri merged 11 commits into
litellm_internal_stagingfrom
litellm_yj_may1_2

Conversation

@yuneng-berri

Copy link
Copy Markdown
Contributor

Relevant issues

Linear ticket

Pre-Submission checklist

Please complete all items before asking a LiteLLM maintainer to review your PR

  • I have Added testing in the tests/test_litellm/ directory, Adding at least 1 test is a hard requirement - see details
  • My PR passes all unit tests on make test-unit
  • My PR's scope is as isolated as possible, it only solves 1 specific problem
  • I have requested a Greptile review by commenting @greptileai and received a Confidence Score of at least 4/5 before requesting a maintainer review

Delays in PR merge?

If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).

CI (LiteLLM team)

CI status guideline:

  • 50-55 passing tests: main is stable with minor issues.
  • 45-49 passing tests: acceptable but needs attention
  • <= 40 passing tests: unstable; be careful with your merges and assess the risk.
  • Branch creation CI run
    Link:

  • CI run for the last commit
    Link:

  • Merge / cherry-pick CI run
    Links:

Screenshots / Proof of Fix

Type

🚄 Infrastructure

Changes

stuxf and others added 11 commits May 1, 2026 07:49
Two changes that together prevent a caller from smuggling unauthorized
models past the API key's allowlist via per-request router overrides.

1. ``_enforce_key_and_fallback_model_access``: also walk fallback models
   nested inside ``router_settings_override.fallbacks`` /
   ``context_window_fallbacks`` / ``content_policy_fallbacks``.
   ``route_llm_request.py`` promotes those to per-request kwargs after
   auth, so without this they bypassed the model allowlist entirely.
   New ``iter_router_fallback_model_names`` helper extracts leaf names
   from both the simple top-level shape (str | {"model": str}) and the
   nested router-config shape ({primary: [fallbacks]}). The two fallback
   validation loops are unified — every name (top-level + override) is
   deduplicated and validated once via ``can_key_call_model`` +
   ``is_valid_fallback_model``.

2. ``route_request``: strip router-internal ``mock_testing_*`` flags
   from user-supplied data. These are testing-only flags that
   deterministically force the router into fallback logic by raising a
   synthetic ``InternalServerError`` etc. Combined with override
   fallbacks they made the smuggling path trivially exploitable. Test
   code that calls the router directly bypasses the strip and is
   unaffected. The strip list is derived from ``MockRouterTestingParams``
   so a new ``mock_testing_*`` flag added to that dataclass is
   automatically covered.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-trust

# Conflicts:
#	tests/test_litellm/proxy/test_route_llm_request.py
CodeQL flagged the previous ``from litellm.types.router import
MockRouterTestingParams`` at module top-level — ``litellm.types.router``
indirectly imports back into proxy modules, so the dataclass may not
exist yet when ``route_llm_request`` is being imported.

Hardcode the three flag names instead, with a guard test
(``test_mock_testing_kwarg_names_matches_dataclass``) that asserts the
hardcoded list matches ``MockRouterTestingParams.fields`` so drift is
caught at test time rather than missed in production.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two related authorization gaps in management endpoints:

1. `/project/update` evaluated permission against the team_id supplied in
   the request body. By passing `data.team_id` pointing at a team they
   admin, a caller could hijack any project — `_check_user_permission_for_project`
   was given the attacker's team_object and happily checked admin
   membership against that. Drop the team_object kwarg so the helper
   re-fetches the existing project's team. Also require admin rights on
   the destination team when reassigning a project across teams, so a
   team admin cannot shed projects into another team's namespace.

2. `/key/update` accepted any `organization_id` and only checked that
   the org existed before applying limits. A caller could thereby point
   their key at an arbitrary org. Add `_validate_caller_can_assign_key_org`
   which enforces the same membership rule already applied on the
   `/key/list` filter path (`validate_key_list_check`); proxy admins and
   no-change updates skip the check.

Tests cover both helpers in isolation: existing-team-admin allow,
unrelated-team admin deny, proxy-admin shortcut, org-member allow,
non-member deny, missing user_id deny, no-memberships deny.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
chore(proxy): tighten router-settings-override and mock-testing trust
Conflict resolution for #26968 dropped the `Iterator` typing import
(NameError at module load), left a dead `fallback_models = cast(...)`
block, and the new tests called `_enforce_key_and_fallback_model_access`
without the now-required `request` kwarg.
…jack

fix(proxy): close project hijacking and key org IDOR (VERIA-55)
…te And Regenerate

Mirrors the membership rule on /key/update so that /key/generate and
/key/{key}/regenerate apply the same `_validate_caller_can_assign_key_org`
gate when the caller specifies an `organization_id`. Proxy admins bypass.
The check no-ops when `organization_id` is not being set.
This file is a regenerable UI build artifact that should not be tracked
in source. Removing so the merge into litellm_internal_staging stays clean.
@greptile-apps

greptile-apps Bot commented May 2, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR patches three distinct authorization gaps (VERIA-44 and VERIA-55): (1) router_settings_override fallback models are now validated against the key's model allowlist alongside top-level fallback fields, (2) router-internal mock_testing_* flags are stripped before routing so they cannot be used to bypass that check, and (3) project-update permission is evaluated against the project's existing team rather than the caller-supplied team, with an extra check requiring destination-team admin rights when reassigning a project — all three code changes are paired with corresponding mock-only unit tests.

Confidence Score: 4/5

Safe to merge; fixes are targeted security patches with good test coverage and no breaking API surface changes.

All findings are P2 (style/best-practice). The security logic itself looks correct — permission checks use the right team, all three fallback fields in both request surfaces are covered, and mock_testing flags are stripped. The only improvement noted is that _validate_caller_can_assign_key_org should route through the get_user_object helper rather than making a raw Prisma call.

litellm/proxy/management_endpoints/key_management_endpoints.py — the new _validate_caller_can_assign_key_org function makes a direct DB call.

Important Files Changed

Filename Overview
enterprise/litellm_enterprise/proxy/management_endpoints/project_endpoints.py Fixes VERIA-55: permission check now uses the project's current team, and team-reassignment requires dual-admin check on both source and destination teams.
litellm/proxy/auth/user_api_key_auth.py Fixes VERIA-44: all three fallback fields (top-level and inside router_settings_override) are now validated against the key's model allowlist; adds iter_router_fallback_model_names helper.
litellm/proxy/management_endpoints/key_management_endpoints.py Adds _validate_caller_can_assign_key_org to enforce org membership on /key/generate, /key/update, and /key/regenerate; direct prisma DB call bypasses existing get_user_object helper.
litellm/proxy/route_llm_request.py Strips router-internal mock_testing_* flags from user-supplied request data before routing, preventing fallback model smuggling (VERIA-44).
tests/test_litellm/proxy/auth/test_router_override_fallback_auth.py New mock-only unit tests covering fallback model validation across all three fallback fields and both top-level and router_settings_override surfaces.
tests/test_litellm/proxy/management_endpoints/test_project_org_authz.py New mock-only unit tests for VERIA-55 covering project permission checks and org-assignment validation.
tests/test_litellm/proxy/test_route_llm_request.py Adds tests verifying mock_testing_* flags are stripped and that _MOCK_TESTING_KWARG_NAMES stays in sync with MockRouterTestingParams dataclass.

Comments Outside Diff (1)

  1. litellm/proxy/management_endpoints/key_management_endpoints.py, line 1226-1229 (link)

    P2 Direct DB query bypasses get_user_object helper

    _validate_caller_can_assign_key_org calls prisma_client.db.litellm_usertable.find_unique directly rather than routing through the established get_user_object helper. Per the team's rule on direct DB access in request-handling paths, helper functions should be preferred so caching, tracing, and future schema changes remain centralized. If get_user_object doesn't yet support an include={"organization_memberships": True} option, extending it there would be safer than a one-off direct query here.

    Rule Used: What: In critical path of request, there should be... (source)

Reviews (1): Last reviewed commit: "[Chore] Proxy/UI: Drop stray _experiment..." | Re-trigger Greptile

@shin-berri
shin-berri merged commit 38ddcda into litellm_internal_staging May 2, 2026
110 of 114 checks passed
@shin-berri
shin-berri deleted the litellm_yj_may1_2 branch May 2, 2026 02:39
fzowl pushed a commit to fzowl/litellm that referenced this pull request Jun 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants