mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-09-20 18:13:49 +00:00
* chore(ci): ignore unpatched nltk GHSA-8mgp-746c-j5xp No patched PyPI release exists beyond 3.10.3. nltk is transitive via crewai-tools[xml] -> unstructured; CrewAI does not call the vulnerable model-artifact APIs. Co-authored-by: Vidit Ostwal <Vidit-Ostwal@users.noreply.github.com> * chore(ci): note dropping nltk GHSA ignore on the next bump Leave an explicit TODO beside the ignore so GHSA-8mgp-746c-j5xp is removed when nltk moves past the unpatched 3.10.3 floor. --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Vidit Ostwal <Vidit-Ostwal@users.noreply.github.com>
157 lines
5.6 KiB
YAML
157 lines
5.6 KiB
YAML
name: Vulnerability Scan
|
|
|
|
on:
|
|
pull_request:
|
|
push:
|
|
branches: [main]
|
|
schedule:
|
|
# Run weekly on Monday at 9:00 UTC
|
|
- cron: '0 9 * * 1'
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
changes:
|
|
name: Detect changes
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
code: ${{ steps.set.outputs.code }}
|
|
steps:
|
|
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
if: github.event_name == 'pull_request'
|
|
- uses: dorny/paths-filter@d1c1ffe0248fe513906c8e24db8ea791d46f8590 # v3
|
|
id: filter
|
|
if: github.event_name == 'pull_request'
|
|
with:
|
|
# Exclusion-only patterns match every non-excluded file under the
|
|
# default "some" quantifier. Require all patterns (including "**")
|
|
# so docs/markdown/Actions-only PRs correctly set code=false.
|
|
predicate-quantifier: every
|
|
filters: |
|
|
code:
|
|
- '**'
|
|
- '!docs/**'
|
|
- '!**/*.md'
|
|
- '!.github/**'
|
|
- name: Set code output
|
|
id: set
|
|
run: |
|
|
if [ "${{ github.event_name }}" != "pull_request" ]; then
|
|
echo "code=true" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "code=${{ steps.filter.outputs.code }}" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
pip-audit:
|
|
name: pip-audit
|
|
needs: changes
|
|
if: needs.changes.outputs.code == 'true'
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Restore global uv cache
|
|
id: cache-restore
|
|
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
|
with:
|
|
path: |
|
|
~/.cache/uv
|
|
~/.local/share/uv
|
|
.venv
|
|
key: uv-main-py3.11-${{ hashFiles('uv.lock') }}
|
|
restore-keys: |
|
|
uv-main-py3.11-
|
|
|
|
- name: Install uv
|
|
uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
|
|
with:
|
|
version: "0.11.3"
|
|
python-version: "3.11"
|
|
enable-cache: false
|
|
|
|
- name: Install dependencies
|
|
run: uv sync --all-groups --all-extras --no-install-project
|
|
|
|
- name: Install pip-audit
|
|
run: uv pip install pip-audit
|
|
|
|
- name: Run pip-audit
|
|
run: |
|
|
pip_audit_args=(
|
|
--desc
|
|
--aliases
|
|
--skip-editable
|
|
--format json
|
|
--output pip-audit-report.json
|
|
# chromadb <=1.5.9: Python HTTP server issues. No PyPI release beyond
|
|
# 1.5.9 yet. CrewAI only uses PersistentClient (embedded), not the
|
|
# HTTP server.
|
|
# GHSA-f4j7-r4q5-qw2c (CVE-2026-45829): pre-auth RCE. Fix merged in
|
|
# chroma-core/chroma#7237.
|
|
--ignore-vuln GHSA-f4j7-r4q5-qw2c
|
|
# GHSA-2wm9-hf6c-p5cr (CVE-2026-45830): authenticated cross-tenant IDOR.
|
|
--ignore-vuln GHSA-2wm9-hf6c-p5cr
|
|
# GHSA-36p7-vc44-83pf (CVE-2026-45833): authenticated trust_remote_code
|
|
# injection on the collection-update endpoint.
|
|
--ignore-vuln GHSA-36p7-vc44-83pf
|
|
# GHSA-xph7-9rjv-w5fr (CVE-2026-45831): SimpleRBACAuthorizationProvider
|
|
# ignores tenant/database/collection scope.
|
|
--ignore-vuln GHSA-xph7-9rjv-w5fr
|
|
# nltk <=3.10.3: GHSA-8mgp-746c-j5xp (CVE-2026-81726): model-artifact
|
|
# APIs bypass pathsec and read/write outside allowed roots. No patched
|
|
# PyPI release yet (fixes are on nltk develop only). Transitive via
|
|
# crewai-tools[xml] -> unstructured; CrewAI does not call those APIs.
|
|
# TODO: drop this ignore when bumping nltk past 3.10.3 to a patched
|
|
# release; keep the ignore list in sync with .pre-commit-config.yaml.
|
|
--ignore-vuln GHSA-8mgp-746c-j5xp
|
|
)
|
|
uv run pip-audit "${pip_audit_args[@]}"
|
|
continue-on-error: true
|
|
|
|
- name: Display results
|
|
if: always()
|
|
run: |
|
|
if [ -f pip-audit-report.json ]; then
|
|
echo "## pip-audit Results" >> $GITHUB_STEP_SUMMARY
|
|
echo '```json' >> $GITHUB_STEP_SUMMARY
|
|
cat pip-audit-report.json | python3 -m json.tool >> $GITHUB_STEP_SUMMARY
|
|
echo '```' >> $GITHUB_STEP_SUMMARY
|
|
# Fail if vulnerabilities found
|
|
python3 -c "
|
|
import json, sys
|
|
with open('pip-audit-report.json') as f:
|
|
data = json.load(f)
|
|
vulns = [d for d in data.get('dependencies', []) if d.get('vulns')]
|
|
if vulns:
|
|
print(f'::error::Found vulnerabilities in {len(vulns)} package(s)')
|
|
for v in vulns:
|
|
for vuln in v['vulns']:
|
|
print(f' - {v[\"name\"]}=={v[\"version\"]}: {vuln[\"id\"]}')
|
|
sys.exit(1)
|
|
print('No known vulnerabilities found')
|
|
"
|
|
else
|
|
echo "::error::pip-audit failed to produce a report. Check the pip-audit step logs."
|
|
exit 1
|
|
fi
|
|
|
|
- name: Upload pip-audit report
|
|
if: always()
|
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
with:
|
|
name: pip-audit-report
|
|
path: pip-audit-report.json
|
|
|
|
- name: Save uv caches
|
|
if: steps.cache-restore.outputs.cache-hit != 'true'
|
|
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
|
with:
|
|
path: |
|
|
~/.cache/uv
|
|
~/.local/share/uv
|
|
.venv
|
|
key: uv-main-py3.11-${{ hashFiles('uv.lock') }}
|