Skip to content

fix(security): resolve all open code-scanning alerts (regex/path sanitizers, workflow perms, docker digest pins)#94

Merged
shudonglin merged 1 commit into
litellm_internal_stagingfrom
fix/codescanning-zero
Jul 5, 2026
Merged

fix(security): resolve all open code-scanning alerts (regex/path sanitizers, workflow perms, docker digest pins)#94
shudonglin merged 1 commit into
litellm_internal_stagingfrom
fix/codescanning-zero

Conversation

@shudonglin

Copy link
Copy Markdown

Summary

Addresses the 13 open code-scanning alerts on this fork:

  • 2 real CodeQL source findings (regex-injection, path-injection) — fixed defensively, behavior preserved.
  • 3 workflow TokenPermissions (high) — reviewed; all three are already minimally-scoped (top-level contents: read, job-level contents: write only on jobs gated to github.repository == 'rayward-external/litellm' that genuinely push a branch). No change needed; recorded as MUST-DISMISS.
  • 8 Dockerfile PinnedDependencies (medium) — 7 were FROM $ARG_VAR lines whose ARG default was already a literal image@sha256:... digest (CodeQL doesn't resolve ARG-indirected FROM); fixed by inlining the already-correct digest, matching the pattern already used for the other stages in the same files. The 8th is a pip install ".[proxy]" line (not a FROM), left as MUST-DISMISS (impractical to hash-pin a local source install).

All digest pins were verified with docker build --check against the real registries (not fabricated) — see test plan.

Per-alert table

# Rule File:line Outcome
1024 py/regex-injection litellm/proxy/auth/auth_checks.py:4290 FIXEDis_model_allowed_by_pattern now builds the match regex via re.escape(allowed_model_pattern).replace(re.escape("*"), ".*") instead of raw f-string interpolation. Verified "bedrock/*" still matches "bedrock/anthropic.claude-3-5-sonnet", "*" still matches anything, and metacharacters in the pattern no longer alter regex semantics.
1025 py/path-injection litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/content_filter.py:448 FIXED — added a os.path.realpath + os.path.commonpath containment check on the resolved category_file_path immediately before os.path.exists/load, logging a warning and skipping the category (not raising) if it escapes categories_dir. Defense-in-depth alongside the pre-existing category_name regex validation.
1021 TokenPermissions .github/workflows/create_daily_oss_agent_shin_branch.yml:16 MUST-DISMISS — job create-oss-agent-shin-branch is gated if: github.repository == 'rayward-external/litellm' and genuinely pushes the daily branch on this fork; top-level permissions are already contents: read, this job-level contents: write is the minimal scope required for its actual write operation.
1022 TokenPermissions .github/workflows/create_daily_staging_branch.yml:16 MUST-DISMISS — same reasoning: create-staging-branch job is fork-gated and pushes the daily staging branch; write is required.
1023 TokenPermissions .github/workflows/create_daily_staging_branch.yml:58 MUST-DISMISS — same reasoning: create-internal-dev-branch job is fork-gated and pushes the daily dev branch; write is required.
1009 PinnedDependencies Dockerfile:17 FIXEDui-builder stage FROM --platform=$BUILDPLATFORM $UI_BUILD_IMAGE → literal node:20.18-alpine3.20@sha256:3488b... (the ARG's own already-correct default), matching the other 3 stages in this file.
1020 PinnedDependencies Dockerfile:34 FIXED — duplicate ui-builder stage, same fix as BerriAI#1009.
1010 PinnedDependencies docker/Dockerfile.database:12 FIXEDuvbin stage FROM $UV_IMAGE → literal ghcr.io/astral-sh/uv:0.11.7@sha256:240fb8....
1011 PinnedDependencies docker/Dockerfile.database:17 FIXEDui-builder stage, same fix as BerriAI#1009.
1012 PinnedDependencies docker/Dockerfile.database:93 FIXEDruntime stage FROM $LITELLM_RUNTIME_IMAGE → literal cgr.dev/chainguard/wolfi-base@sha256:c61ac69....
1013 PinnedDependencies docker/Dockerfile.non_root:11 FIXEDuvbin stage, same fix as BerriAI#1010.
1014 PinnedDependencies docker/Dockerfile.non_root:16 FIXEDui-builder stage, same fix as BerriAI#1009.
1019 PinnedDependencies litellm-rust/crates/ai-gateway/Dockerfile:63 MUST-DISMISSRUN pip install --no-cache-dir ".[proxy]" installs this repo's own source tree (copied in via COPY litellm/ ./litellm/ above), not a versioned PyPI release; impractical/meaningless to hash-pin.

Test plan

  • python3 -m py_compile litellm/proxy/auth/auth_checks.py litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/content_filter.py — clean
  • python3 -c "import yaml; ..." over both flagged workflow files — clean (no edits made, since both were already minimally-scoped)
  • docker build --check -f Dockerfile . — 1 pre-existing unrelated warning (DuplicateStageName on the ui-builder stage, present before this PR), no errors; both new digests resolved against the real registries
  • docker build --check -f docker/Dockerfile.database . — clean
  • docker build --check -f docker/Dockerfile.non_root . — clean
  • is_model_allowed_by_pattern behavior spot-check: "bedrock/*" still matches "bedrock/anthropic.claude-3-5-sonnet", "*" still matches anything, unrelated model strings still rejected

🤖 Generated with Claude Code

…flow perms, docker pins)

- auth_checks.py: re.escape() the wildcard pattern in
  is_model_allowed_by_pattern before building the match regex (py/regex-injection, BerriAI#1024).
- content_filter.py: add a realpath/commonpath containment re-check on the
  resolved category_file_path immediately before use, as defense-in-depth
  alongside the existing category_name regex validation (py/path-injection, BerriAI#1025).
- Dockerfile / docker/Dockerfile.database / docker/Dockerfile.non_root: pin the
  remaining ARG-variable FROM lines (uvbin, ui-builder, runtime) to their
  already-known-good literal image@sha256 digests, matching the pattern already
  used for the other stages in these files (PinnedDependencies BerriAI#1009, BerriAI#1010,
  BerriAI#1011, BerriAI#1012, BerriAI#1013, BerriAI#1014, BerriAI#1020). Verified with `docker build --check`.
- .github/fork-patches.txt: track the above as fork patches to reapply after
  upstream syncs.

Workflow TokenPermissions alerts (BerriAI#1021, BerriAI#1022, BerriAI#1023) and the ai-gateway
Dockerfile pip install (BerriAI#1019) were reviewed and left as-is; see PR description
for per-alert MUST-DISMISS reasoning.
@shudonglin shudonglin changed the title security: drive code-scanning alerts to zero fix(security): resolve all open code-scanning alerts (regex/path sanitizers, workflow perms, docker digest pins) Jul 5, 2026
@shudonglin shudonglin merged commit 55ed732 into litellm_internal_staging Jul 5, 2026
78 of 79 checks passed
@shudonglin shudonglin deleted the fix/codescanning-zero branch July 5, 2026 14:39
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.

1 participant