fix: validate header names/values and prevent CRLF injection (#1817) #201
Workflow file for this run
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
| name: Trivy Vulnerability Scan | |
| on: | |
| push: | |
| branches: [main] | |
| paths: | |
| - "backend/Dockerfile" | |
| - "frontend/Dockerfile" | |
| - "backend/requirements*.txt" | |
| - "frontend/package*.json" | |
| - ".github/workflows/trivy-scan.yml" | |
| pull_request: | |
| branches: [main] | |
| paths: | |
| - "backend/Dockerfile" | |
| - "frontend/Dockerfile" | |
| - "backend/requirements*.txt" | |
| - "frontend/package*.json" | |
| - ".github/workflows/trivy-scan.yml" | |
| schedule: | |
| - cron: "0 6 * * 1" | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| security-events: write | |
| jobs: | |
| build: | |
| name: Build ${{ matrix.service }} image | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - service: backend | |
| context: ./backend | |
| dockerfile: ./backend/Dockerfile | |
| image: secuscan-backend | |
| - service: frontend | |
| context: ./frontend | |
| dockerfile: ./frontend/Dockerfile | |
| image: secuscan-frontend | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Build ${{ matrix.service }} image | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: ${{ matrix.context }} | |
| file: ${{ matrix.dockerfile }} | |
| push: false | |
| load: true | |
| tags: ${{ matrix.image }}:ci | |
| cache-from: type=gha,scope=${{ matrix.service }} | |
| cache-to: type=gha,scope=${{ matrix.service }},mode=max | |
| - name: Save image as tar | |
| run: docker save ${{ matrix.image }}:ci -o /tmp/${{ matrix.image }}.tar | |
| - name: Upload image artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ matrix.image }}-tar | |
| path: /tmp/${{ matrix.image }}.tar | |
| retention-days: 1 | |
| trivy-scan: | |
| name: Trivy scan - ${{ matrix.service }} | |
| runs-on: ubuntu-latest | |
| needs: build | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - service: backend | |
| image: secuscan-backend | |
| - service: frontend | |
| image: secuscan-frontend | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Download image artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: ${{ matrix.image }}-tar | |
| path: /tmp | |
| - name: Load image | |
| run: docker load -i /tmp/${{ matrix.image }}.tar | |
| - name: Run Trivy - table output | |
| uses: aquasecurity/[email protected] | |
| with: | |
| image-ref: ${{ matrix.image }}:ci | |
| format: table | |
| exit-code: "0" | |
| ignore-unfixed: true | |
| vuln-type: os,library | |
| severity: CRITICAL,HIGH | |
| - name: Run Trivy - SARIF report | |
| uses: aquasecurity/[email protected] | |
| with: | |
| image-ref: ${{ matrix.image }}:ci | |
| format: sarif | |
| output: trivy-${{ matrix.service }}.sarif | |
| ignore-unfixed: true | |
| vuln-type: os,library | |
| severity: CRITICAL,HIGH | |
| - name: Upload SARIF to GitHub Security | |
| uses: github/codeql-action/upload-sarif@v3 | |
| if: always() | |
| with: | |
| sarif_file: trivy-${{ matrix.service }}.sarif | |
| category: trivy-${{ matrix.service }} | |
| - name: Run Trivy - JSON report | |
| uses: aquasecurity/[email protected] | |
| with: | |
| image-ref: ${{ matrix.image }}:ci | |
| format: json | |
| output: trivy-${{ matrix.service }}.json | |
| ignore-unfixed: true | |
| vuln-type: os,library | |
| severity: CRITICAL,HIGH | |
| - name: Upload JSON vulnerability report | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: trivy-report-${{ matrix.service }} | |
| path: trivy-${{ matrix.service }}.json | |
| retention-days: 30 | |
| - name: Fail on CRITICAL vulnerabilities | |
| uses: aquasecurity/[email protected] | |
| with: | |
| image-ref: ${{ matrix.image }}:ci | |
| format: table | |
| exit-code: "1" | |
| ignore-unfixed: true | |
| vuln-type: os,library | |
| severity: CRITICAL | |
| synthetic-cve-test: | |
| name: Synthetic CVE policy gate test | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Pull deliberately vulnerable image | |
| run: docker pull python:3.8.20-slim-bullseye | |
| - name: Trivy scan of vulnerable image - expect non-zero exit | |
| id: vuln_scan | |
| continue-on-error: true | |
| uses: aquasecurity/[email protected] | |
| with: | |
| image-ref: python:3.8.20-slim-bullseye | |
| format: table | |
| exit-code: "1" | |
| ignore-unfixed: false | |
| vuln-type: os,library | |
| severity: CRITICAL | |
| - name: Assert scan correctly failed | |
| run: | | |
| if [ "${{ steps.vuln_scan.outcome }}" = "failure" ]; then | |
| echo "PASS: Policy gate correctly rejected a known-vulnerable image." | |
| else | |
| echo "FAIL: Policy gate did NOT reject a known-vulnerable image." | |
| exit 1 | |
| fi |