From ac2d349161fa92af4527ca6ea80cb7264859f959 Mon Sep 17 00:00:00 2001 From: Ishaan Jaff Date: Mon, 8 Sep 2025 16:49:52 -0700 Subject: [PATCH] =?UTF-8?q?[Security]=20Ensure=20LiteLLM=20Images=20have?= =?UTF-8?q?=200=20Critical,=20High,=20Medium=20vulnerabilities=20with=20CV?= =?UTF-8?q?SS=20=E2=89=A5=204.0=20(#14357)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * updated scans * fix scans * fix litellm_security_tests * fix * fix count CVEE * add readme * fix Security Scans * fix: starlette==0.47.2 # starlette fastapi dep * bump fastapi==0.115.14 * bump 0.116.1 --- .circleci/config.yml | 88 +++++++++++++++------------ ci_cd/security_scans.sh | 105 +++++++++++++++++++++++++++++++++ ci_cd/security_scans_readme.md | 9 +++ requirements.txt | 3 +- 4 files changed, 167 insertions(+), 38 deletions(-) create mode 100755 ci_cd/security_scans.sh create mode 100644 ci_cd/security_scans_readme.md diff --git a/.circleci/config.yml b/.circleci/config.yml index 7debc582915..caa7f26b0ad 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -535,11 +535,9 @@ jobs: - litellm_router_coverage.xml - litellm_router_coverage litellm_security_tests: - docker: - - image: cimg/python:3.11 - auth: - username: ${DOCKERHUB_USERNAME} - password: ${DOCKERHUB_PASSWORD} + machine: + image: ubuntu-2204:2023.10.1 + resource_class: xlarge working_directory: ~/project steps: - checkout @@ -548,32 +546,65 @@ jobs: name: Show git commit hash command: | echo "Git commit hash: $CIRCLE_SHA1" + - run: + name: Install Docker CLI (In case it's not already installed) + command: | + sudo apt-get update + sudo apt-get install -y docker-ce docker-ce-cli containerd.io + - run: + name: Install Python 3.9 + command: | + curl https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh --output miniconda.sh + bash miniconda.sh -b -p $HOME/miniconda + export PATH="$HOME/miniconda/bin:$PATH" + conda init bash + source ~/.bashrc + conda create -n myenv python=3.9 -y + conda activate myenv + python --version - run: name: Install Dependencies command: | + pip install "pytest==7.3.1" + pip install "pytest-asyncio==0.21.1" + pip install aiohttp python -m pip install --upgrade pip - python -m pip install -r requirements.txt + python -m pip install -r .circleci/requirements.txt pip install "pytest==7.3.1" pip install "pytest-retry==1.6.3" + pip install "pytest-mock==3.12.0" pip install "pytest-asyncio==0.21.1" - pip install "pytest-cov==5.0.0" + pip install mypy + pip install "google-generativeai==0.3.2" + pip install "google-cloud-aiplatform==1.43.0" + pip install pyarrow + pip install "boto3==1.36.0" + pip install "aioboto3==13.4.0" + pip install langchain + pip install "langfuse>=2.0.0" + pip install "logfire==0.29.0" + pip install numpydoc + pip install prisma + pip install fastapi + pip install jsonschema + pip install "httpx==0.24.1" + pip install "gunicorn==21.2.0" + pip install "anyio==3.7.1" + pip install "aiodynamo==23.10.1" + pip install "asyncio==3.4.3" + pip install "PyGithub==1.59.1" + pip install "openai==1.100.1" - run: - name: Install Trivy + name: Install dockerize command: | - sudo apt-get update - sudo apt-get install wget apt-transport-https gnupg lsb-release - wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add - - echo "deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | sudo tee -a /etc/apt/sources.list.d/trivy.list - sudo apt-get update - sudo apt-get install trivy + wget https://github.com/jwilder/dockerize/releases/download/v0.6.1/dockerize-linux-amd64-v0.6.1.tar.gz + sudo tar -C /usr/local/bin -xzvf dockerize-linux-amd64-v0.6.1.tar.gz + rm dockerize-linux-amd64-v0.6.1.tar.gz - run: - name: Run Trivy scan on LiteLLM Docs + name: Run Security Scans command: | - trivy fs --scanners vuln --dependency-tree --exit-code 1 --severity HIGH,CRITICAL,MEDIUM ./docs/ - - run: - name: Run Trivy scan on LiteLLM UI - command: | - trivy fs --scanners vuln --dependency-tree --exit-code 1 --severity HIGH,CRITICAL,MEDIUM ./ui/ + chmod +x ci_cd/security_scans.sh + ./ci_cd/security_scans.sh - run: name: Run prisma ./docker/entrypoint.sh command: | @@ -1593,23 +1624,6 @@ jobs: - run: name: Wait for PostgreSQL to be ready command: dockerize -wait tcp://localhost:5432 -timeout 1m - - run: - name: Install Grype - command: | - curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sudo sh -s -- -b /usr/local/bin - - run: - name: Build and Scan Docker Images - command: | - # Build and scan Dockerfile.database - echo "Building and scanning Dockerfile.database..." - docker build -t litellm-database:latest -f ./docker/Dockerfile.database . - grype litellm-database:latest --fail-on critical - - - # Build and scan main Dockerfile - echo "Building and scanning main Dockerfile..." - docker build -t litellm:latest . - grype litellm:latest --fail-on critical - run: name: Build Docker image command: docker build -t my-app:latest -f ./docker/Dockerfile.database . diff --git a/ci_cd/security_scans.sh b/ci_cd/security_scans.sh new file mode 100755 index 00000000000..dbf7c657f6f --- /dev/null +++ b/ci_cd/security_scans.sh @@ -0,0 +1,105 @@ +#!/bin/bash + +# Security Scans Script for LiteLLM +# This script runs comprehensive security scans including Trivy and Grype + +set -e + +echo "Starting security scans for LiteLLM..." + +# Function to install Trivy and required tools +install_trivy() { + echo "Installing Trivy and required tools..." + sudo apt-get update + sudo apt-get install -y wget apt-transport-https gnupg lsb-release jq curl + wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add - + echo "deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | sudo tee -a /etc/apt/sources.list.d/trivy.list + sudo apt-get update + sudo apt-get install trivy + echo "Trivy and required tools installed successfully" +} + +# Function to install Grype +install_grype() { + echo "Installing Grype..." + curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sudo sh -s -- -b /usr/local/bin + echo "Grype installed successfully" +} + +# Function to run Trivy scans +run_trivy_scans() { + echo "Running Trivy scans..." + + echo "Scanning LiteLLM Docs..." + trivy fs --scanners vuln --dependency-tree --exit-code 1 --severity HIGH,CRITICAL,MEDIUM ./docs/ + + echo "Scanning LiteLLM UI..." + trivy fs --scanners vuln --dependency-tree --exit-code 1 --severity HIGH,CRITICAL,MEDIUM ./ui/ + + echo "Trivy scans completed successfully" +} + +# Function to build and scan Docker images with Grype +run_grype_scans() { + echo "Running Grype scans..." + + # Temporarily add wheel files to .dockerignore for security scans + echo "Temporarily modifying .dockerignore to exclude problematic wheel files..." + cp .dockerignore .dockerignore.backup 2>/dev/null || touch .dockerignore.backup + echo "/*.whl" >> .dockerignore + + # Build and scan Dockerfile.database + echo "Building and scanning Dockerfile.database..." + docker build -t litellm-database:latest -f ./docker/Dockerfile.database . + grype litellm-database:latest --fail-on critical + + # Build and scan main Dockerfile + echo "Building and scanning main Dockerfile..." + docker build -t litellm:latest . + grype litellm:latest --fail-on critical + + # Restore original .dockerignore + echo "Restoring original .dockerignore..." + mv .dockerignore.backup .dockerignore + + # Scan the locally built LiteLLM image for vulnerabilities with CVSS >= 4.0 + echo "Scanning locally built LiteLLM image for high-severity vulnerabilities..." + echo "Using locally built image: litellm:latest" + + # Run grype scan and check for vulnerabilities with CVSS >= 4.0 + echo "Checking for vulnerabilities with CVSS score >= 4.0..." + HIGH_SEVERITY_COUNT=$(grype litellm:latest -o json | jq -r '.matches[] | select(.vulnerability.cvss[]?.metrics.baseScore >= 4.0) | .vulnerability.id' | wc -l) + + if [ "$HIGH_SEVERITY_COUNT" -gt 0 ]; then + echo "ERROR: Found $HIGH_SEVERITY_COUNT vulnerabilities with CVSS score >= 4.0 in litellm:latest" + echo "Detailed vulnerability report:" + grype litellm:latest -o json | jq -r ' + ["Package", "Version", "Vulnerability ID", "CVSS Score", "Severity", "Fix Version", "Description"], + (.matches[] | select(.vulnerability.cvss[]?.metrics.baseScore >= 4.0) | + [.artifact.name, .artifact.version, .vulnerability.id, .vulnerability.cvss[0].metrics.baseScore, .vulnerability.severity, (.vulnerability.fix.versions[0] // "No fix available"), .vulnerability.description]) | + @tsv' | column -t -s $'\t' + exit 1 + else + echo "No high-severity vulnerabilities (CVSS >= 4.0) found in litellm:latest" + fi + + echo "Grype scans completed successfully" +} + +# Main execution +main() { + echo "Installing security scanning tools..." + install_trivy + install_grype + + echo "Running filesystem vulnerability scans..." + run_trivy_scans + + echo "Running Docker image vulnerability scans..." + run_grype_scans + + echo "All security scans completed successfully!" +} + +# Execute main function +main "$@" diff --git a/ci_cd/security_scans_readme.md b/ci_cd/security_scans_readme.md new file mode 100644 index 00000000000..dd64b01c296 --- /dev/null +++ b/ci_cd/security_scans_readme.md @@ -0,0 +1,9 @@ +# Security Scans + +## Scans that run: + +- Trivy scan on `./docs/` (HIGH/CRITICAL/MEDIUM) +- Trivy scan on `./ui/` (HIGH/CRITICAL/MEDIUM) +- Grype scan on `Dockerfile.database` (fails on CRITICAL) +- Grype scan on main `Dockerfile` (fails on CRITICAL) +- Grype CVSS ≥ 4.0 scan on main `Dockerfile` (fails any vulnerabilities with CVSS ≥ 4.0) diff --git a/requirements.txt b/requirements.txt index 2d31819dc5b..93bd491a211 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,8 @@ anyio==4.8.0 # openai + http req. httpx==0.28.1 openai==1.99.5 # openai req. -fastapi==0.115.5 # server dep +fastapi==0.116.1 # server dep +starlette==0.47.2 # starlette fastapi dep backoff==2.2.1 # server dep pyyaml==6.0.2 # server dep uvicorn==0.29.0 # server dep