Skip to content

Bitropy patches on v1.83.7-stable.patch.1: CVE-2026-42208 SQLi fix + passthrough patches#3

Open
pkieszcz wants to merge 4 commits intov1.83.7-stable-basefrom
bitropy/v1.83.7-stable-patched
Open

Bitropy patches on v1.83.7-stable.patch.1: CVE-2026-42208 SQLi fix + passthrough patches#3
pkieszcz wants to merge 4 commits intov1.83.7-stable-basefrom
bitropy/v1.83.7-stable-patched

Conversation

@pkieszcz
Copy link
Copy Markdown

What this is

Bitropy patches rebased onto upstream v1.83.7-stable.patch.1 to pick up the fix for CVE-2026-42208 (critical pre-auth SQL injection in LiteLLM, bleepingcomputer writeup).

Replaces our previous bitropy/v1.82.3-stable-patched branch (PR #2).

Patches

Same 2 patches as PR #2, cherry-picked onto the new base:

1. Strip x-litellm-api-key from forwarded headers (security)

File: litellm/passthrough/utils.py

Without this, the x-litellm-api-key proxy auth header is forwarded to upstream providers, leaking our virtual keys.

Upstream PR: BerriAI#20432 (still open / unreviewed).

2. Credential priority for Anthropic passthrough (critical)

File: litellm/proxy/pass_through_endpoints/llm_passthrough_endpoints.py

Without this, the proxy always sends its own x-api-key to Anthropic, which:

  • Leaks x-api-key: None upstream when no server ANTHROPIC_API_KEY is set
  • Overwrites client-provided credentials (OAuth tokens, BYOK keys) even when a server key IS set

Behavior with this patch:

Client sends Server has key Result
OAuth token (Claude Max) Any Client credential is forwarded (Max subscription pays)
Own x-api-key (BYOK) Any Client credential is forwarded
Nothing Yes Server ANTHROPIC_API_KEY injected (or ANTHROPIC_AUTH_TOKEN env, new in 1.83.x)
Nothing No Empty headers — Anthropic returns 401

The merge picks up upstream's new AnthropicModelInfo.get_auth_header() (added in f415b72, supporting ANTHROPIC_AUTH_TOKEN) for the server-fallback branch only — client credentials still take priority.

Why upgrade now

  • CVE-2026-42208: active exploitation reported. Fix lands in upstream v1.83.7+.
  • The 2 Bitropy patches above remain unmerged upstream as of v1.83.7, so we keep our fork.

Testing

Tested locally on the built image with a header-echo upstream (mendhak/http-https-echo):

  • x-litellm-api-key is NOT present in upstream request
  • ✅ Client OAuth (Authorization: Bearer sk-ant-oat-...) reaches upstream as-is
  • ✅ Client BYOK (x-api-key: sk-ant-...) reaches upstream as-is
  • ✅ No client creds + server ANTHROPIC_API_KEY → server key injected as x-api-key
  • ✅ No client creds + no server key → no auth header injected
  • ✅ Wrong/missing x-litellm-api-key → proxy auth rejects with 401 before forwarding

Deploy

Image: europe-central2-docker.pkg.dev/bitropy-management/images/litellm:v1.83.7-stable-patched
Digest: sha256:cc49ca17bdc4aad76182d7007d71d7a6eb696a4df02e6f7d4df157412fe4d674

Multi-arch manifest list (linux/amd64 + linux/arm64) — Kubernetes auto-selects the right arch.

Claude Code config (unchanged)

{
  "env": {
    "ANTHROPIC_BASE_URL": "https://ai.demo.internal.bitropy.io/anthropic",
    "ANTHROPIC_CUSTOM_HEADERS": "x-litellm-api-key: sk-<your-virtual-key>"
  }
}

Use ANTHROPIC_CUSTOM_HEADERS, NOT ANTHROPIC_API_KEY — the latter would set x-api-key and the credential-priority patch would treat it as BYOK and pass it straight through.

klaudworks and others added 4 commits April 30, 2026 09:43
…ream providers

Prevent x-litellm-api-key (LiteLLM's virtual key) from being leaked
to upstream providers when _forward_headers=True is used in passthrough
endpoints.
Client-provided credentials now take precedence over server credentials
in the /anthropic/ passthrough endpoint. This enables mixed mode where:

1. Client sends x-api-key → forwarded as-is (user pays via own API key)
2. Client sends Authorization → forwarded as-is (user pays via OAuth/Max)
3. No client credentials + server ANTHROPIC_API_KEY → server key used
4. No client credentials + no server key → no credentials forwarded

Previously the server always sent x-api-key (even literal "None" when
unconfigured), overwriting any client-provided credentials and breaking
Claude Code Max (OAuth) and BYOK scenarios.

Supersedes the simpler one-liner from d742c76 on v1.81.12-stable-patched.
Based on the approach from PR BerriAI#20429 (closed) and reverted PR BerriAI#14821.
Defect 2 root cause: update_in_memory_guardrail passed Prisma's raw dict
directly to update_in_memory_litellm_params, which calls vars() on it,
raising TypeError and silently swallowing every DB update.  Hot-reload
of any guardrail param (presidio_language, score thresholds, URL bases,
pii_entities_config, ...) was therefore broken — pod restart was the
only way to pick up DB changes.

Fix: isinstance(dict) -> LitellmParams(**data) conversion before the
call, matching the existing pattern in initialize_guardrail.  After
this, the base class blanket setattr in update_in_memory_litellm_params
propagates all Pydantic fields without any per-field copy in subclasses.

Linear: https://linear.app/bitropy/issue/BIT-455
Defect 3: anonymize_text iterated redacted_text["items"] and applied
new_text = new_text[:start] + replacement + new_text[end:] using item
coordinates.  Presidio's /anonymize returns item start/end as positions
in the OUTPUT text (where each mask token sits after redaction), not
in the original.  Applying them to the original drifts proportional to
len(replacement) - len(original_span), corrupting masked output on any
non-trivial input.

Fix:
- output_parse_pii=False: return redacted_text["text"] verbatim — no
  re-stitching needed, Presidio already produced the correct output.
- output_parse_pii=True: iterate analyze_results (pre-anonymize, with
  original-text coordinates) for both stitching and pii_tokens
  construction.  Eliminates the secondary bug where pii_tokens stored
  text[start:end] using already-mutated coordinates.

Fail-closed on /anonymize backend error preserved.

Linear: https://linear.app/bitropy/issue/BIT-455
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