diff --git a/.github/workflows/run-ci-cd.yaml b/.github/workflows/run-ci-cd.yaml index 843074ac33..d218ab2400 100644 --- a/.github/workflows/run-ci-cd.yaml +++ b/.github/workflows/run-ci-cd.yaml @@ -121,8 +121,8 @@ jobs: run: | make check-spelling - scan-code: - name: Run Code Scan + run-security-scan-code: + name: Run code security scan needs: - check-frontend - pre-commit @@ -134,38 +134,23 @@ jobs: - name: Check out repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd - - name: Setup Trivy - uses: aquasecurity/setup-trivy@3fb12ec12f41e471780db15c232d5dd185dcb514 - with: - cache: true + - name: Run Semgrep security scan + run: make security-scan-code-semgrep - - name: Run Trivy Repository Scan - uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 + - name: Upload Semgrep report + if: always() + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f with: - scan-type: repo - skip-setup-trivy: true - trivy-config: trivy.yaml - timeout-minutes: 5 - - scan-ci-dependencies: - name: Run CI Dependencies Scan - needs: - - check-frontend - - pre-commit - - spellcheck - permissions: - contents: read - runs-on: ubuntu-latest - steps: - - name: Check out repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + name: semgrep-results-run-${{ github.run_number }} + path: semgrep-security-report.txt + retention-days: 14 - name: Setup Trivy uses: aquasecurity/setup-trivy@3fb12ec12f41e471780db15c232d5dd185dcb514 with: cache: true - - name: Run Trivy Filesystem Scan + - name: Run Trivy security scan uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 with: scan-type: fs @@ -173,37 +158,10 @@ jobs: trivy-config: trivy.yaml timeout-minutes: 5 - run-security-scan: - name: Run security scan - needs: - - check-frontend - - pre-commit - - spellcheck - permissions: - contents: read - runs-on: ubuntu-latest - steps: - - name: Check out repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd - - - name: Run Security CI Scan - run: make security-scan - - - name: Upload security scan report - if: always() - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f - with: - name: semgrep-results-run-${{ github.run_number }} - path: semgrep-security-report.txt - retention-days: 14 - timeout-minutes: 5 - run-backend-tests: name: Run backend tests needs: - - run-security-scan - - scan-code - - scan-ci-dependencies + - run-security-scan-code permissions: contents: read id-token: write @@ -253,9 +211,7 @@ jobs: run-frontend-unit-tests: name: Run frontend unit tests needs: - - run-security-scan - - scan-code - - scan-ci-dependencies + - run-security-scan-code permissions: contents: read id-token: write @@ -304,9 +260,7 @@ jobs: run-frontend-e2e-tests: name: Run frontend e2e tests needs: - - run-security-scan - - scan-code - - scan-ci-dependencies + - run-security-scan-code permissions: contents: read runs-on: ubuntu-latest @@ -397,9 +351,7 @@ jobs: run-frontend-a11y-tests: name: Run frontend accessibility tests needs: - - run-security-scan - - scan-code - - scan-ci-dependencies + - run-security-scan-code permissions: contents: read runs-on: ubuntu-latest @@ -450,9 +402,7 @@ jobs: name: Run GraphQL fuzz tests if: false needs: - - run-security-scan - - scan-code - - scan-ci-dependencies + - run-security-scan-code uses: ./.github/workflows/run-fuzz-tests.yaml with: test-file: graphql_test.py @@ -460,9 +410,7 @@ jobs: run-rest-fuzz-tests: name: Run REST fuzz tests needs: - - run-security-scan - - scan-code - - scan-ci-dependencies + - run-security-scan-code uses: ./.github/workflows/run-fuzz-tests.yaml with: test-file: rest_test.py diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index feaea6a6a1..85c0319928 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -406,6 +406,41 @@ make test This command runs tests and checks that coverage threshold requirements are satisfied for both backend and frontend. **Please note your PR won't be merged if it fails the code tests checks.** +### Running Security Scan + +Run the security scans for vulnerabilities and anti-patterns with the following command: + +```bash +make security-scan +``` + +This command automatically: + +- Performs local Semgrep and Trivy scans +- Outputs findings to the terminal for immediate review + +For addressing findings: + +- Review the output for specific file paths and line numbers +- Follow the documentation links provided in the output for remediation guidance +- Use # NOSEMGREP to suppress confirmed false positives while adding a short comment explaining each suppression + +#### Running Code Scans Only + +You can run code scan part separately via + +```bash +make security-scan-code +``` + +#### Running Image Scans Only + +You can run image scan part separately via + +```bash +make security-scan-images +``` + ### Running e2e Tests Run the frontend e2e tests with the following command: diff --git a/Makefile b/Makefile index a6f8d205e1..a84ad67998 100644 --- a/Makefile +++ b/Makefile @@ -56,12 +56,20 @@ run: docker compose -f docker-compose/local/compose.yaml --project-name nest-local build && \ docker compose -f docker-compose/local/compose.yaml --project-name nest-local up --remove-orphans -scan-images: \ - scan-backend-image \ - scan-frontend-image +security-scan: \ + security-scan-code \ + security-scan-images -security-scan: - @echo "Running Security Scan..." +security-scan-code: \ + security-scan-code-semgrep \ + security-scan-code-trivy + +security-scan-images: \ + security-scan-backend-image \ + security-scan-frontend-image + +security-scan-code-semgrep: + @echo "Running Semgrep security scan..." @docker run --rm \ -v "$(PWD):/src" \ -w /src \ @@ -98,6 +106,16 @@ security-scan: --text-output=semgrep-security-report.txt \ . +security-scan-code-trivy: + @echo "Running Trivy security scan..." + @docker run \ + --rm \ + -v "$(PWD):/src" \ + -w /src \ + aquasec/trivy fs \ + --config trivy.yaml \ + . + test: \ test-nest-app diff --git a/backend/Makefile b/backend/Makefile index 611f8be014..e946e35b6c 100644 --- a/backend/Makefile +++ b/backend/Makefile @@ -157,7 +157,7 @@ save-backup: @CMD="python manage.py dumpdata --natural-primary --natural-foreign --indent=2" $(MAKE) exec-backend-command > backend/data/backup.json @gzip backend/data/backup.json -scan-backend-image: build-backend-local-image +security-scan-backend-image: build-backend-local-image @trivy image \ --config trivy.yaml \ --docker-host $$(docker context inspect --format '{{.Endpoints.docker.Host}}' 2>/dev/null) \ diff --git a/cspell/custom-dict.txt b/cspell/custom-dict.txt index 219fedcddb..a75033249e 100644 --- a/cspell/custom-dict.txt +++ b/cspell/custom-dict.txt @@ -58,6 +58,7 @@ algoliasearch ansa apexcharts apk +aquasec aquasecurity arithmatex arkid15r diff --git a/frontend/Makefile b/frontend/Makefile index 5331db78e4..0b704abfa2 100644 --- a/frontend/Makefile +++ b/frontend/Makefile @@ -56,7 +56,7 @@ generate-graphql-types: || (printf "pnpm run graphql-codegen"; for i in $$(seq 1 49); do printf "."; done; printf "\033[37;41mFailed\033[0m\n" \ && pnpm run graphql-codegen)) -scan-frontend-image: build-frontend-local-image +security-scan-frontend-image: build-frontend-local-image @trivy image \ --config trivy.yaml \ --docker-host $$(docker context inspect --format '{{.Endpoints.docker.Host}}' 2>/dev/null) \