mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-05 08:07:05 +00:00
ci(security): add workflow to block .pth files in PRs
Add a security gate workflow that scans pull requests for malicious .pth file additions or renames. .pth files are a known Python security risk as they allow arbitrary code execution at interpreter startup. The workflow will fail the check if any .pth files are detected, prompting the author to rename legitimate fixtures to .pth.txt. chore: remove malicious.pth file The file was identified as potentially harmful and has been deleted to maintain repository security. ci: update actions/github-script to pinned version v7.0.1 Update the GitHub Actions workflow to use a pinned version tag instead of a commit hash for the `actions/github-script` action. This improves maintainability and security by using an official, versioned release. docs: add security gate check to PR templates and improve scan Update CONTRIBUTING.md and pull request template to document the new Critical Entry Point Scan requirement. Enhance the security-gate workflow with a warning for large PRs exceeding GitHub API limits and add configuration notes for branch protection.
This commit is contained in:
parent
08be1e52ae
commit
e2a4bef3a9
3 changed files with 77 additions and 0 deletions
1
.github/pull_request_template.md
vendored
1
.github/pull_request_template.md
vendored
|
|
@ -10,6 +10,7 @@
|
|||
- [ ] My PR passes all unit tests on [`make test-unit`](https://docs.litellm.ai/docs/extras/contributing_code)
|
||||
- [ ] 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
|
||||
- [ ] (LiteLLM Team Only) I have confirmed that the **Critical Entry Point Scan** (from `.github/workflows/security-gate.yml`) is passing and is configured as a required status check in the branch protection rules.
|
||||
|
||||
## Delays in PR merge?
|
||||
|
||||
|
|
|
|||
75
.github/workflows/security-gate.yml
vendored
Normal file
75
.github/workflows/security-gate.yml
vendored
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
name: 🛡️ PR Security Gate v2
|
||||
|
||||
# NOTE: This workflow MUST be configured as a 'Required Status Check' in the repository's
|
||||
# branch protection rules for 'main' and 'master' branches to effectively block merges.
|
||||
# Settings -> Branches -> Branch protection rules -> [Branch] -> Require status checks to pass -> 'Critical Entry Point Scan'
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ main, master ]
|
||||
types: [ opened, synchronize, reopened ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
|
||||
jobs:
|
||||
supply-chain-check:
|
||||
name: Critical Entry Point Scan
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- name: Detect Malicious .pth Files
|
||||
uses: actions/github-script@v7.0.1
|
||||
with:
|
||||
script: |
|
||||
const owner = context.repo.owner;
|
||||
const repo = context.repo.repo;
|
||||
const pull_number = context.payload.pull_request.number;
|
||||
|
||||
const suspects = [];
|
||||
let totalFiles = 0;
|
||||
|
||||
for await (const page of github.paginate.iterator(github.rest.pulls.listFiles, {
|
||||
owner,
|
||||
repo,
|
||||
pull_number,
|
||||
per_page: 100,
|
||||
})) {
|
||||
totalFiles += page.data.length;
|
||||
for (const f of page.data) {
|
||||
const status = (f.status || '').toLowerCase();
|
||||
const newName = (f.filename || '').toLowerCase();
|
||||
|
||||
if (status === 'removed') {
|
||||
continue; // ignore deletions
|
||||
}
|
||||
|
||||
if (status === 'renamed') {
|
||||
if (newName.endsWith('.pth')) {
|
||||
suspects.push(f.filename);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (newName.endsWith('.pth')) {
|
||||
suspects.push(f.filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (totalFiles >= 300) {
|
||||
core.warning(
|
||||
`PR has ${totalFiles} files. GitHub API limit for listFiles may have been reached (approx. 300-3000 depending on API version) — this security scan may be incomplete. Please manually verify if large numbers of files were added.`
|
||||
);
|
||||
}
|
||||
|
||||
if (suspects.length > 0) {
|
||||
core.setFailed(
|
||||
`SECURITY ALERT: .pth file(s) detected in PR diff:\n${suspects.join('\n')}\n` +
|
||||
`REASON: .pth files allow arbitrary code execution at Python startup.\n` +
|
||||
`If this is a legitimate test fixture, rename it to .pth.txt`
|
||||
);
|
||||
} else {
|
||||
core.info('No suspicious entry points found.');
|
||||
}
|
||||
|
|
@ -15,6 +15,7 @@ Here are the core requirements for any PR submitted to LiteLLM:
|
|||
- [ ] **Ensure your PR passes all checks**:
|
||||
- [ ] [Unit Tests](#running-unit-tests) - `make test-unit`
|
||||
- [ ] [Linting / Formatting](#running-linting-and-formatting-checks) - `make lint`
|
||||
- [ ] **Security Gate** - Ensure the `Critical Entry Point Scan` (`security-gate.yml`) passes on your PR.
|
||||
|
||||
#### UI PRs
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue