Skip to content

add test(tag-routing): prevent header regex bypass for strict plain t… - #26805

Merged
yuneng-berri merged 2 commits into
litellm_internal_stagingfrom
litellm_auth_bypass_tag_based_routing
May 1, 2026
Merged

add test(tag-routing): prevent header regex bypass for strict plain t…#26805
yuneng-berri merged 2 commits into
litellm_internal_stagingfrom
litellm_auth_bypass_tag_based_routing

Conversation

@harish-berri

@harish-berri harish-berri commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

Update strict tag check logic so deployments with plain tags cannot fall back to header regex matching when tag_filtering_match_any=false. Also improve the conditional readability by naming the plain-tag check explicitly.

Add tests to validate the condition

improve the conditional readability by naming the plain-tag check explicitly.

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

🆕 New Feature
🐛 Bug Fix
🧹 Refactoring
📖 Documentation
🚄 Infrastructure
✅ Test

Changes

…ags.

Add tests to validate the condition

 improve the conditional readability by naming the plain-tag check explicitly.
@greptile-apps

greptile-apps Bot commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR refactors the strict_tag_check_failed condition in _match_deployment by extracting bool(deployment_tags) into a named deployment_has_plain_tags variable, and adds a unit test verifying that regex header matching is blocked under match_any=False when a deployment has plain tags. The code change is a readability improvement only — the two expressions are semantically equivalent for Optional[List[str]], so no runtime behavior changes.

Confidence Score: 4/5

Safe to merge — no behavioral change, just a cosmetic refactor with an added test.

Only P2 findings: the PR description overstates a refactor as a bug fix, and the new test is missing the complementary match_any=True assertion. No P0 or P1 issues.

No files require special attention.

Important Files Changed

Filename Overview
litellm/router_strategy/tag_based_routing.py Refactors bool(deployment_tags) into a named deployment_has_plain_tags variable for readability; no behavioral change since the two expressions are semantically identical for Optional[List[str]].
tests/test_litellm/router_strategy/test_router_tag_routing.py Adds a well-scoped unit test verifying regex fallback is blocked under match_any=False; uses no network calls and imports locally — but lacks the complementary match_any=True assertion to fully pin both directions of the condition.

Reviews (1): Last reviewed commit: "add test(tag-routing): prevent header re..." | Re-trigger Greptile

Comment on lines +349 to +374
def test_strict_tag_routing_without_request_tags_blocks_header_regex_fallback():
"""
When tag_filtering_match_any=False, deployments with plain tags must require
those request tags before header regex can match. A spoofed User-Agent must
not route to a tagged deployment when the request has no tags.
"""
from litellm.router_strategy.tag_based_routing import _match_deployment

deployment = {
"model_name": "restricted-model",
"litellm_params": {
"model": "gpt-4o",
"tags": ["internal"],
"tag_regex": ["^User-Agent: internal-tool"],
},
}

assert (
_match_deployment(
deployment=deployment,
request_tags=None,
header_strings=["User-Agent: internal-tool"],
match_any=False,
)
is None
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Missing complementary test case for match_any=True

The new test only validates that regex is blocked under match_any=False. The symmetric case — that regex fallback still works under match_any=True when request tags are absent — is not covered. Without it, a future accidental tightening of the condition (e.g. removing the not match_any guard) would silently break the permissive path.

Consider adding:

assert (
    _match_deployment(
        deployment=deployment,
        request_tags=None,
        header_strings=["User-Agent: internal-tool"],
        match_any=True,  # permissive mode — regex fallback should be allowed
    )
    is not None
)

Comment on lines +109 to +110
deployment_has_plain_tags = deployment_tags is not None and len(deployment_tags) > 0
strict_tag_check_failed = not match_any and deployment_has_plain_tags

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Behavior is identical to the original expression

bool(deployment_tags) evaluates to False for both None and [], and to True for any non-empty list — exactly the same semantics as deployment_tags is not None and len(deployment_tags) > 0 for an Optional[List[str]] value. This is purely a readability refactor, not a functional fix. The PR description frames it as preventing a bypass, but the old code already guarded correctly. The named variable is a nice clarity improvement, but it may be worth aligning the commit message and PR description to accurately reflect this as a refactor + test addition rather than a bug fix, so future readers of the git history have correct context.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@codecov

codecov Bot commented May 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@yuneng-berri
yuneng-berri merged commit eab0075 into litellm_internal_staging May 1, 2026
117 checks passed
@yuneng-berri
yuneng-berri deleted the litellm_auth_bypass_tag_based_routing branch May 1, 2026 07:08
fzowl pushed a commit to fzowl/litellm that referenced this pull request Jun 24, 2026
…_based_routing

add test(tag-routing): prevent header regex bypass for strict plain t…
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.

2 participants