diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml new file mode 100644 index 00000000000..a9ecdc5c261 --- /dev/null +++ b/.github/workflows/semgrep.yml @@ -0,0 +1,28 @@ +# Semgrep: run only custom rules (.semgrep/rules) – no registry/auto rules. +# Fast, no timeouts from heavy JS/Python registry rules on large files. +name: Semgrep (custom rules only) + +on: + pull_request: + branches: [main] + push: + branches: [main] + +jobs: + semgrep: + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.12" + + - name: Install Semgrep + run: pip install semgrep + + - name: Run Semgrep (custom rules only) + run: semgrep scan --config .semgrep/rules . --error diff --git a/.semgrep/rules/README.md b/.semgrep/rules/README.md new file mode 100644 index 00000000000..0dbb77cdd48 --- /dev/null +++ b/.semgrep/rules/README.md @@ -0,0 +1,22 @@ +# Custom Semgrep rules for LiteLLM + +Add custom rule YAML files here. Semgrep loads all `.yml`/`.yaml` files under this directory. + +**Run only custom rules (CI / fail on findings):** + +```bash +semgrep scan --config .semgrep/rules . --error +``` + +**Run with registry + custom rules:** + +```bash +semgrep scan --config auto --config .semgrep/rules . +``` + +**Layout:** + +- `python/` – Python-specific rules (security, patterns) +- Add more subdirs as needed (e.g. `generic/` for language-agnostic rules) + +See [Semgrep rule syntax](https://semgrep.dev/docs/writing-rules/rule-syntax/). diff --git a/.semgrep/rules/python/unbounded-memory.yml b/.semgrep/rules/python/unbounded-memory.yml new file mode 100644 index 00000000000..18b18b7944a --- /dev/null +++ b/.semgrep/rules/python/unbounded-memory.yml @@ -0,0 +1,15 @@ +# Unbounded memory growth – data structures without a clear max limit +# Can lead to OOM under load or with unbounded input. + +rules: + # asyncio.Queue() with no maxsize is unbounded – bad pattern for integrations (log queues, etc.) + - id: unbounded-asyncio-queue + message: asyncio.Queue() with no maxsize can grow unbounded. Use asyncio.Queue(maxsize=N) for integrations (e.g. log queues). + severity: WARNING + languages: [python] + pattern-either: + - pattern: asyncio.Queue() + - pattern: asyncio.Queue(maxsize=0) + metadata: + category: correctness + cwe: "CWE-400: Uncontrolled Resource Consumption"