deps(deps): update uvicorn[standard] requirement from >=0.46.0 to >=0.47.0 #98
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Workflow: skanowanie znanych podatnosci w zaleznosciach (uv.lock). | |
| # Praktyka #6 z lirantal/pypi-security-best-practices. | |
| # | |
| # Triggers: | |
| # - push do dev/master: kazda zmiana w lockfile sprawdza sie od razu | |
| # - pull_request: PR-y dotykajace zaleznosci nie merguja sie z aktywnym CVE | |
| # - weekly cron: nowo-disclosed CVE wykryte tez na "spokojnym" lockfile | |
| # | |
| # Tool: pip-audit (PyPA-official, autorzy pip-a). Wczesniej uzywalismy | |
| # uv-secure ale projekt zostal zarchiwizowany 18 kwietnia 2026 (read-only | |
| # repo, ostatnie release v0.17.2). Stale CVE database = false sense of | |
| # security. pip-audit jest aktywnie maintained przez PyPA i czyta z tego | |
| # samego PyPI Advisory DB co uv-secure. | |
| # | |
| # uv.lock -> requirements.txt przez `uv export --no-dev` (jak w multi-scanner). | |
| # | |
| # Polityka: | |
| # - Vulnerability z fix-em dostepnym (fix_versions non-empty): failure. | |
| # pip-audit nie ma natywnego severity filter, ale fix-availability juz | |
| # jest dobrym proxy: jezeli upstream wypuscil fix, znaczy ze warto bumpnac. | |
| # - Vuln bez fixa: warning w job summary, nie blokuje (nic nie da sie zrobic). | |
| # - Whitelist znanych non-impact CVE przez --ignore-vuln (patrz job ponizej). | |
| # | |
| # Defense-in-depth: drugi job (multi-scanner) odpala OSV-Scanner, Grype | |
| # i Trivy na SBOM-ie wygenerowanym z uv.lock. Wszystkie report-only - | |
| # pip-audit pozostaje jedynym gate-em release-u. | |
| name: Dependency vulnerability scan | |
| on: | |
| push: | |
| branches: [dev, master] | |
| paths: | |
| - "uv.lock" | |
| - "pyproject.toml" | |
| - ".github/workflows/dependency-audit.yml" | |
| pull_request: | |
| paths: | |
| - "uv.lock" | |
| - "pyproject.toml" | |
| schedule: | |
| # poniedzialek 06:00 UTC - po Dependabot weekly run, wylapuje | |
| # CVE ktore wyszly w weekend | |
| - cron: "0 6 * * 1" | |
| workflow_dispatch: # manualne uruchomienie z UI | |
| permissions: | |
| contents: read | |
| jobs: | |
| pip-audit: | |
| name: pip-audit scan | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 | |
| - name: Export uv.lock -> requirements.txt (prod-only) | |
| run: | | |
| mkdir -p /tmp/audit | |
| uv export --no-dev --format requirements-txt --no-hashes --quiet \ | |
| -o /tmp/audit/requirements.txt | |
| # Whitelist znanych non-impact CVE. | |
| # --- | |
| # CVE-2026-42304 / GHSA-grgv-6hw6-v9g4 (twisted < 26.4.0rc2): | |
| # DoS w twisted.names.dns.Name.decode przez glebokie DNS compression | |
| # pointer chains. BPP NIE uruchamia DNS-servera Twisted (twisted jest | |
| # transitive zaleznoscia daphne + autobahn dla WebSocket/Channels, | |
| # bez modulu twisted.names). Fix dostepny tylko w 26.4.0rc2 (release | |
| # candidate) - nie wprowadzamy RC do produkcji do czasu stable release. | |
| # Re-evaluate przy bumpie twisted do 26.x stable. | |
| - name: Run pip-audit (gate on fixable) | |
| run: | | |
| uvx --from pip-audit pip-audit \ | |
| --requirement /tmp/audit/requirements.txt \ | |
| --disable-pip \ | |
| --no-deps \ | |
| --format columns \ | |
| --ignore-vuln CVE-2026-42304 | |
| - name: Run pip-audit (JSON full report - non-blocking) | |
| if: always() | |
| run: | | |
| uvx --from pip-audit pip-audit \ | |
| --requirement /tmp/audit/requirements.txt \ | |
| --disable-pip \ | |
| --no-deps \ | |
| --format json \ | |
| --output /tmp/audit/full.json || true | |
| { | |
| echo "## pip-audit full report" | |
| echo "" | |
| count=$(jq '[.dependencies[]?.vulns[]?] | length' \ | |
| /tmp/audit/full.json 2>/dev/null || echo 0) | |
| if [ "$count" -gt 0 ]; then | |
| echo "Znaleziono **$count** vulnerabilities (vs gate-policy)." | |
| echo "" | |
| echo '| Pakiet | Wersja | CVE | Fix versions |' | |
| echo '|---|---|---|---|' | |
| jq -r ' | |
| .dependencies[]? | . as $p | | |
| .vulns[]? | | |
| "| \($p.name) | \($p.version) | \(.id) | \(.fix_versions | join(", ")) |" | |
| ' /tmp/audit/full.json | sort -u | |
| else | |
| echo "Brak findings." | |
| fi | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| # Defense-in-depth: trzy dodatkowe skanery (OSV/Grype/Trivy) na SBOM | |
| # wygenerowanym z uv.lock. Kazdy z innej bazy CVE - lapia rozne | |
| # rzeczy niz uv-secure (osv.dev, anchore, aquasecurity vs PyPA-DB). | |
| # WSZYSTKIE w trybie report-only (continue-on-error: true) - jedynym | |
| # gate-em release-u pozostaje uv-secure powyzej. Multi-scanner ma dac | |
| # WIDOCZNOSC, nie zablokowac merga falszywym pozytywem z roznicy baz. | |
| multi-scanner: | |
| name: Multi-scanner (OSV / Grype / Trivy) — report-only | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 | |
| - name: Generate SBOM (CycloneDX, prod-only) | |
| run: | | |
| mkdir -p /tmp/sbom | |
| uv export --no-dev --format requirements-txt --no-hashes --quiet \ | |
| -o /tmp/sbom/requirements.txt | |
| uvx --quiet --from cyclonedx-bom cyclonedx-py requirements \ | |
| /tmp/sbom/requirements.txt \ | |
| --output-reproducible \ | |
| --output-format JSON \ | |
| --output-file /tmp/sbom/sbom.json \ | |
| --pyproject pyproject.toml | |
| echo "Pakietow w SBOM: $(jq '.components | length' /tmp/sbom/sbom.json)" | |
| - name: Install scanners | |
| run: | | |
| # OSV-Scanner (Google) - binarka GitHub release | |
| curl -sSL -o /usr/local/bin/osv-scanner \ | |
| https://github.com/google/osv-scanner/releases/latest/download/osv-scanner_linux_amd64 | |
| chmod +x /usr/local/bin/osv-scanner | |
| # Grype (Anchore) - oficjalny installer | |
| curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh \ | |
| | sh -s -- -b /usr/local/bin | |
| # Trivy (Aqua) - oficjalny installer | |
| curl -sSfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh \ | |
| | sh -s -- -b /usr/local/bin | |
| - name: OSV-Scanner — wszystkie findings | |
| continue-on-error: true | |
| run: | | |
| osv-scanner scan source --sbom=/tmp/sbom/sbom.json \ | |
| --format=json --output=/tmp/sbom/osv.json 2>/dev/null || true | |
| { | |
| echo "## OSV-Scanner (Google)" | |
| echo "" | |
| count=$(jq '[.results[]?.packages[]?.vulnerabilities[]?] | length' \ | |
| /tmp/sbom/osv.json 2>/dev/null || echo 0) | |
| if [ "$count" -gt 0 ]; then | |
| echo "Znaleziono **$count** vulnerabilities." | |
| echo "" | |
| echo '| Pakiet | CVE |' | |
| echo '|---|---|' | |
| jq -r ' | |
| .results[]? | .packages[]? | . as $p | | |
| .vulnerabilities[]? | | |
| "| \($p.package.name)@\($p.package.version) | \(.id) |" | |
| ' /tmp/sbom/osv.json | sort -u | |
| else | |
| echo "Brak findings." | |
| fi | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| - name: Grype — HIGH/CRITICAL | |
| continue-on-error: true | |
| run: | | |
| grype "sbom:/tmp/sbom/sbom.json" -o json --file /tmp/sbom/grype.json \ | |
| >/dev/null 2>&1 || true | |
| { | |
| echo "## Grype (Anchore)" | |
| echo "" | |
| count=$(jq '[.matches[]? | select(.vulnerability.severity | test("^(High|Critical)$"; "i"))] | length' \ | |
| /tmp/sbom/grype.json 2>/dev/null || echo 0) | |
| if [ "$count" -gt 0 ]; then | |
| echo "Znaleziono **$count** HIGH/CRITICAL." | |
| echo "" | |
| echo '| Pakiet | CVE | Severity | Fix |' | |
| echo '|---|---|---|---|' | |
| jq -r ' | |
| .matches[]? | | |
| select(.vulnerability.severity | test("^(High|Critical)$"; "i")) | | |
| "| \(.artifact.name)@\(.artifact.version) | \(.vulnerability.id) | \(.vulnerability.severity) | \(.vulnerability.fix.versions[]? // "no-fix") |" | |
| ' /tmp/sbom/grype.json | sort -u | |
| else | |
| echo "Brak findings (HIGH/CRITICAL)." | |
| fi | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| - name: Trivy — HIGH/CRITICAL z fix-em | |
| continue-on-error: true | |
| run: | | |
| # --ignore-unfixed: wyciszamy CVE bez dostepnego fixa (jak w | |
| # build-docker-images.yml - nic nie mozna zrobic, samo szum). | |
| # --severity HIGH,CRITICAL: bez tego Trivy zglasza wszystko | |
| # ze swojej bardzo agresywnej DB - filter sprowadza to do | |
| # realnie waznych rzeczy. | |
| trivy sbom /tmp/sbom/sbom.json \ | |
| --severity HIGH,CRITICAL \ | |
| --ignore-unfixed \ | |
| --format json \ | |
| --output /tmp/sbom/trivy.json \ | |
| --quiet 2>/dev/null || true | |
| { | |
| echo "## Trivy (Aqua Security)" | |
| echo "" | |
| count=$(jq '[.Results[]?.Vulnerabilities[]?] | length' \ | |
| /tmp/sbom/trivy.json 2>/dev/null || echo 0) | |
| if [ "$count" -gt 0 ]; then | |
| echo "Znaleziono **$count** HIGH/CRITICAL z dostepnym fixem." | |
| echo "" | |
| echo '| Pakiet | CVE | Severity | Fix |' | |
| echo '|---|---|---|---|' | |
| jq -r ' | |
| .Results[]? | .Vulnerabilities[]? | | |
| "| \(.PkgName)@\(.InstalledVersion) | \(.VulnerabilityID) | \(.Severity) | \(.FixedVersion // "no-fix") |" | |
| ' /tmp/sbom/trivy.json | sort -u | |
| else | |
| echo "Brak findings (HIGH/CRITICAL z fix-em)." | |
| fi | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| - name: Upload SBOM + raporty (artifact, retention 30d) | |
| if: always() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: dependency-scan-${{ github.run_id }} | |
| path: /tmp/sbom/ | |
| retention-days: 30 |