From faaa47c2742376a7981af649bbc542ec3d3dfd08 Mon Sep 17 00:00:00 2001 From: Muhammad Hassaan Saleem Date: Fri, 30 Jan 2026 10:44:29 +0500 Subject: [PATCH 01/17] feat: add Dockerfile for Trivy version tracking Signed-off-by: Muhammad Hassaan Saleem --- docker/trivy/Dockerfile | 1 + 1 file changed, 1 insertion(+) create mode 100644 docker/trivy/Dockerfile diff --git a/docker/trivy/Dockerfile b/docker/trivy/Dockerfile new file mode 100644 index 0000000000..6dd8bd84e8 --- /dev/null +++ b/docker/trivy/Dockerfile @@ -0,0 +1 @@ +FROM aquasec/trivy:0.58.0 \ No newline at end of file From 9f4a200bb7120a379cc52cc632ef25465c34f5a4 Mon Sep 17 00:00:00 2001 From: Muhammad Hassaan Saleem Date: Fri, 30 Jan 2026 10:45:18 +0500 Subject: [PATCH 02/17] build: add dynamic Trivy versioning and caching to root Makefile Signed-off-by: Muhammad Hassaan Saleem --- Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index a84ad67998..9db5f7bf50 100644 --- a/Makefile +++ b/Makefile @@ -111,9 +111,11 @@ security-scan-code-trivy: @docker run \ --rm \ -v "$(PWD):/src" \ + -v trivy-cache:/root/.cache/trivy \ -w /src \ - aquasec/trivy fs \ - --config trivy.yaml \ + $$(grep -E '^FROM aquasec/trivy:' docker/trivy/Dockerfile | sed 's/^FROM //') \ + fs \ + --config trivy.yaml . test: \ From 14d9ca2e5b2f4d18eb76431d19f9e31d70fe498e Mon Sep 17 00:00:00 2001 From: Muhammad Hassaan Saleem Date: Fri, 30 Jan 2026 10:45:59 +0500 Subject: [PATCH 03/17] build(backend): implement standardized security scan target Signed-off-by: Muhammad Hassaan Saleem --- backend/Makefile | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/backend/Makefile b/backend/Makefile index 1411db9f60..8a3bb13f04 100644 --- a/backend/Makefile +++ b/backend/Makefile @@ -157,13 +157,24 @@ 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 -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) \ - --exit-code 1 \ +# vars (defalts for Local dev) +BACKEND_IMAGE_NAME ?= nest-backend-local +TRIVY_EXIT_CODE ?= 0 + +security-scan-backend-image: + @if [ "$(BACKEND_IMAGE_NAME)" = "nest-backend-local" ]; then \ + $(MAKE) build-backend-local-image; \ + fi + @echo "Scanning $(BACKEND_IMAGE_NAME)..." + @docker run --rm \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v trivy-cache:/root/.cache/trivy \ + $$(grep -E '^FROM aquasec/trivy:' docker/trivy/Dockerfile | sed 's/^FROM //') \ + image \ + --exit-code $(TRIVY_EXIT_CODE) \ --severity CRITICAL,HIGH \ - nest-backend-local + --no-progress \ + $(BACKEND_IMAGE_NAME) shell-backend: @CMD="/bin/sh" $(MAKE) exec-backend-command-it From 975068336ca8bdb04bd6c99a45ad925f07a3dc1f Mon Sep 17 00:00:00 2001 From: Muhammad Hassaan Saleem Date: Fri, 30 Jan 2026 10:46:26 +0500 Subject: [PATCH 04/17] build(frontend): implement standardized security scan target Signed-off-by: Muhammad Hassaan Saleem --- frontend/Makefile | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/frontend/Makefile b/frontend/Makefile index 0b704abfa2..6275ab64cc 100644 --- a/frontend/Makefile +++ b/frontend/Makefile @@ -56,13 +56,24 @@ 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)) -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) \ - --exit-code 1 \ +# Defaults for Local Development +FRONTEND_IMAGE_NAME ?= nest-frontend-local +TRIVY_EXIT_CODE ?= 0 + +security-scan-frontend-image: + @if [ "$(FRONTEND_IMAGE_NAME)" = "nest-frontend-local" ]; then \ + $(MAKE) build-frontend-local-image; \ + fi + @echo "Scanning $(FRONTEND_IMAGE_NAME)..." + @docker run --rm \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v trivy-cache:/root/.cache/trivy \ + $$(grep -E '^FROM aquasec/trivy:' docker/trivy/Dockerfile | sed 's/^FROM //') \ + image \ + --exit-code $(TRIVY_EXIT_CODE) \ --severity CRITICAL,HIGH \ - nest-frontend-local + --no-progress \ + $(FRONTEND_IMAGE_NAME) shell-frontend: @CMD="/bin/sh" $(MAKE) exec-frontend-command-it From e58c7b5b5387277e075b0ee2f81b08c31d37238e Mon Sep 17 00:00:00 2001 From: Muhammad Hassaan Saleem Date: Fri, 30 Jan 2026 10:47:13 +0500 Subject: [PATCH 05/17] ci: refactor workflow to use Makefile targets for security scans Signed-off-by: Muhammad Hassaan Saleem --- .github/workflows/run-ci-cd.yaml | 56 +++++++------------------------- 1 file changed, 12 insertions(+), 44 deletions(-) diff --git a/.github/workflows/run-ci-cd.yaml b/.github/workflows/run-ci-cd.yaml index ae716cfb9c..d59d1688b3 100644 --- a/.github/workflows/run-ci-cd.yaml +++ b/.github/workflows/run-ci-cd.yaml @@ -551,28 +551,12 @@ jobs: - name: Check out repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd - - name: Setup Trivy - uses: aquasecurity/setup-trivy@3fb12ec12f41e471780db15c232d5dd185dcb514 - with: - cache: true - - - name: Scan backend image - uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 - with: - exit-code: 1 - image-ref: owasp/nest:backend-staging - scan-type: image - skip-setup-trivy: true - trivy-config: trivy.yaml - - - name: Scan frontend image - uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 - with: - exit-code: 1 - image-ref: owasp/nest:frontend-staging - scan-type: image - skip-setup-trivy: true - trivy-config: trivy.yaml + - name: Run Trivy security scan via Makefile + run: | + make security-scan-images \ + BACKEND_IMAGE_NAME=owasp/nest:backend-staging \ + FRONTEND_IMAGE_NAME=owasp/nest:frontend-staging \ + TRIVY_EXIT_CODE=1 timeout-minutes: 5 deploy-staging-nest: @@ -921,28 +905,12 @@ jobs: - name: Check out repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd - - name: Setup Trivy - uses: aquasecurity/setup-trivy@3fb12ec12f41e471780db15c232d5dd185dcb514 - with: - cache: true - - - name: Scan backend image - uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 - with: - exit-code: 1 - image-ref: owasp/nest:backend-production - scan-type: image - skip-setup-trivy: true - trivy-config: trivy.yaml - - - name: Scan frontend image - uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 - with: - exit-code: 1 - image-ref: owasp/nest:frontend-production - scan-type: image - skip-setup-trivy: true - trivy-config: trivy.yaml + - name: Run Trivy security scan via Makefile + run: | + make security-scan-images \ + BACKEND_IMAGE_NAME=owasp/nest:backend-production \ + FRONTEND_IMAGE_NAME=owasp/nest:frontend-production \ + TRIVY_EXIT_CODE=1 timeout-minutes: 5 deploy-production-nest: From 23a0a53041bc840bfc9e0c8c01aef56212ee1696 Mon Sep 17 00:00:00 2001 From: hassaansaleem28 Date: Fri, 30 Jan 2026 12:56:25 +0500 Subject: [PATCH 06/17] style: apply pre-commit auto-fixes Signed-off-by: hassaansaleem28 --- backend/manage.py | 0 docker/trivy/Dockerfile | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) mode change 100755 => 100644 backend/manage.py diff --git a/backend/manage.py b/backend/manage.py old mode 100755 new mode 100644 diff --git a/docker/trivy/Dockerfile b/docker/trivy/Dockerfile index 6dd8bd84e8..98d917e88a 100644 --- a/docker/trivy/Dockerfile +++ b/docker/trivy/Dockerfile @@ -1 +1 @@ -FROM aquasec/trivy:0.58.0 \ No newline at end of file +FROM aquasec/trivy:0.58.0 From 4ed573a9eaec0fce6cf62625866c31990374eec5 Mon Sep 17 00:00:00 2001 From: hassaansaleem28 Date: Fri, 30 Jan 2026 14:40:36 +0500 Subject: [PATCH 07/17] fix: add missing line continuation in security-scan-code target Signed-off-by: hassaansaleem28 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9db5f7bf50..6b5406b927 100644 --- a/Makefile +++ b/Makefile @@ -115,7 +115,7 @@ security-scan-code-trivy: -w /src \ $$(grep -E '^FROM aquasec/trivy:' docker/trivy/Dockerfile | sed 's/^FROM //') \ fs \ - --config trivy.yaml + --config trivy.yaml \ . test: \ From 645764f23048eaedf21b50780108fe42eb645fee Mon Sep 17 00:00:00 2001 From: hassaansaleem28 Date: Fri, 30 Jan 2026 15:27:14 +0500 Subject: [PATCH 08/17] fix: restore executable permission to manage.py Signed-off-by: hassaansaleem28 --- backend/manage.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 backend/manage.py diff --git a/backend/manage.py b/backend/manage.py old mode 100644 new mode 100755 From f494533c112b661514e84789f718c52ac0895e13 Mon Sep 17 00:00:00 2001 From: Arkadii Yakovets Date: Fri, 30 Jan 2026 10:16:33 -0800 Subject: [PATCH 09/17] Update code --- Makefile | 6 +++--- backend/Makefile | 5 +++-- backend/apps/owasp/Makefile | 2 +- cspell/Makefile | 4 ++-- frontend/Makefile | 5 +++-- trivy.yaml | 2 ++ 6 files changed, 14 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index 6b5406b927..7ea2ea378e 100644 --- a/Makefile +++ b/Makefile @@ -71,7 +71,7 @@ security-scan-images: \ security-scan-code-semgrep: @echo "Running Semgrep security scan..." @docker run --rm \ - -v "$(PWD):/src" \ + -v "$(CURDIR):/src" \ -w /src \ $$(grep -E '^FROM semgrep/semgrep:' docker/semgrep/Dockerfile | sed 's/^FROM //') \ semgrep \ @@ -110,13 +110,13 @@ security-scan-code-trivy: @echo "Running Trivy security scan..." @docker run \ --rm \ - -v "$(PWD):/src" \ + -v "$(CURDIR):/src" \ -v trivy-cache:/root/.cache/trivy \ -w /src \ $$(grep -E '^FROM aquasec/trivy:' docker/trivy/Dockerfile | sed 's/^FROM //') \ fs \ --config trivy.yaml \ - . + . test: \ test-nest-app diff --git a/backend/Makefile b/backend/Makefile index 8a3bb13f04..3b713cdab1 100644 --- a/backend/Makefile +++ b/backend/Makefile @@ -169,11 +169,12 @@ security-scan-backend-image: @docker run --rm \ -v /var/run/docker.sock:/var/run/docker.sock \ -v trivy-cache:/root/.cache/trivy \ + -v "$(CURDIR):/src" \ + -w /src \ $$(grep -E '^FROM aquasec/trivy:' docker/trivy/Dockerfile | sed 's/^FROM //') \ image \ + --config /src/trivy.yaml \ --exit-code $(TRIVY_EXIT_CODE) \ - --severity CRITICAL,HIGH \ - --no-progress \ $(BACKEND_IMAGE_NAME) shell-backend: diff --git a/backend/apps/owasp/Makefile b/backend/apps/owasp/Makefile index c74b6e8362..7c5f7733eb 100644 --- a/backend/apps/owasp/Makefile +++ b/backend/apps/owasp/Makefile @@ -41,7 +41,7 @@ owasp-generate-community-snapshot-video: @mkdir -p backend/generated_videos @docker run \ --env-file backend/.env \ - --mount type=bind,src="$(PWD)/backend/generated_videos",dst=/home/owasp/generated_videos \ + --mount type=bind,src="$(CURDIR)/backend/generated_videos",dst=/home/owasp/generated_videos \ --network nest-local_nest-network \ --rm \ nest-snapshot-video \ diff --git a/cspell/Makefile b/cspell/Makefile index 441568ea57..04ac58e60a 100644 --- a/cspell/Makefile +++ b/cspell/Makefile @@ -11,14 +11,14 @@ cspell-check: cspell-install cspell-run cspell-run: @docker run \ - --mount type=bind,src="$(PWD)",dst=/nest \ + --mount type=bind,src="$(CURDIR)",dst=/nest \ --rm \ cspell -c cspell/cspell.json "$(CMD)" update-cspell-dependencies: cspell-install @-docker run \ -it \ - --mount type=bind,src="$(PWD)",dst=/nest \ + --mount type=bind,src="$(CURDIR)",dst=/nest \ --entrypoint=/bin/sh \ --workdir=/nest/cspell \ --rm \ diff --git a/frontend/Makefile b/frontend/Makefile index 6275ab64cc..6050eace64 100644 --- a/frontend/Makefile +++ b/frontend/Makefile @@ -68,11 +68,12 @@ security-scan-frontend-image: @docker run --rm \ -v /var/run/docker.sock:/var/run/docker.sock \ -v trivy-cache:/root/.cache/trivy \ + -v "$(CURDIR):/src" \ + -w /src \ $$(grep -E '^FROM aquasec/trivy:' docker/trivy/Dockerfile | sed 's/^FROM //') \ image \ + --config /src/trivy.yaml \ --exit-code $(TRIVY_EXIT_CODE) \ - --severity CRITICAL,HIGH \ - --no-progress \ $(FRONTEND_IMAGE_NAME) shell-frontend: diff --git a/trivy.yaml b/trivy.yaml index af3f13a633..54725c937e 100644 --- a/trivy.yaml +++ b/trivy.yaml @@ -11,6 +11,8 @@ severity: - HIGH - UNKNOWN +show-suppressed: true + timeout: 10m vulnerability: From 72018c12b2b6de63cda4c9f15b3d884d8f69e262 Mon Sep 17 00:00:00 2001 From: Muhammad Hassaan Saleem Date: Sun, 1 Feb 2026 23:55:24 +0500 Subject: [PATCH 10/17] fix(ci): align ci workflows with makefiles Signed-off-by: Muhammad Hassaan Saleem --- .github/workflows/run-ci-cd.yaml | 20 +++++--- Makefile | 88 ++++++++++++++------------------ backend/Makefile | 49 +++++++++++++++--- docker/frontend/Dockerfile | 17 ++++++ frontend/Makefile | 44 +++++++++++++--- frontend/next.config.ts | 2 +- 6 files changed, 149 insertions(+), 71 deletions(-) diff --git a/.github/workflows/run-ci-cd.yaml b/.github/workflows/run-ci-cd.yaml index 8d26107f51..98d91e6c3f 100644 --- a/.github/workflows/run-ci-cd.yaml +++ b/.github/workflows/run-ci-cd.yaml @@ -151,11 +151,11 @@ jobs: cache: true - name: Run Trivy security scan - uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 - with: - scan-type: fs - skip-setup-trivy: true - trivy-config: trivy.yaml + run: | + make backend-security-scan-code + make frontend-security-scan-code + make backend-security-scan-secrets + make frontend-security-scan-secrets timeout-minutes: 5 run-backend-tests: @@ -553,8 +553,11 @@ jobs: - name: Run Trivy security scan via Makefile run: | - make security-scan-images \ + make backend-security-scan-image \ BACKEND_IMAGE_NAME=owasp/nest:backend-staging \ + TRIVY_EXIT_CODE=1 + + make frontend-security-scan-image \ FRONTEND_IMAGE_NAME=owasp/nest:frontend-staging \ TRIVY_EXIT_CODE=1 timeout-minutes: 5 @@ -907,8 +910,11 @@ jobs: - name: Run Trivy security scan via Makefile run: | - make security-scan-images \ + make backend-security-scan-image \ BACKEND_IMAGE_NAME=owasp/nest:backend-production \ + TRIVY_EXIT_CODE=1 + + make frontend-security-scan-image \ FRONTEND_IMAGE_NAME=owasp/nest:frontend-production \ TRIVY_EXIT_CODE=1 timeout-minutes: 5 diff --git a/Makefile b/Makefile index 7ea2ea378e..2fa2e7a46a 100644 --- a/Makefile +++ b/Makefile @@ -56,66 +56,54 @@ 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 +# Default Local Safe Scan NO Secrets security-scan: \ - security-scan-code \ - security-scan-images - -security-scan-code: \ security-scan-code-semgrep \ - security-scan-code-trivy + backend-security-scan \ + frontend-security-scan -security-scan-images: \ - security-scan-backend-image \ - security-scan-frontend-image +# CI/CD full Scan +security-scan-full: \ + security-scan \ + backend-security-scan-secrets \ + frontend-security-scan-secrets security-scan-code-semgrep: @echo "Running Semgrep security scan..." @docker run --rm \ - -v "$(CURDIR):/src" \ + -v "$(PWD):/src" \ -w /src \ $$(grep -E '^FROM semgrep/semgrep:' docker/semgrep/Dockerfile | sed 's/^FROM //') \ semgrep \ - --config p/ci \ - --config p/command-injection \ - --config p/cwe-top-25 \ - --config p/default \ - --config p/django \ - --config p/docker \ - --config p/docker-compose \ - --config p/dockerfile \ - --config p/javascript \ - --config p/nextjs \ - --config p/nginx \ - --config p/nodejs \ - --config p/owasp-top-ten \ - --config p/python \ - --config p/r2c-security-audit \ - --config p/react \ - --config p/secrets \ - --config p/secure-defaults \ - --config p/security-audit \ - --config p/security-headers \ - --config p/sql-injection \ - --config p/terraform \ - --config p/typescript \ - --error \ - --skip-unknown-extensions \ - --timeout 10 \ - --timeout-threshold 3 \ - --text \ - --text-output=semgrep-security-report.txt \ - . - -security-scan-code-trivy: - @echo "Running Trivy security scan..." - @docker run \ - --rm \ - -v "$(CURDIR):/src" \ - -v trivy-cache:/root/.cache/trivy \ - -w /src \ - $$(grep -E '^FROM aquasec/trivy:' docker/trivy/Dockerfile | sed 's/^FROM //') \ - fs \ - --config trivy.yaml \ + --config p/ci \ + --config p/command-injection \ + --config p/cwe-top-25 \ + --config p/default \ + --config p/django \ + --config p/docker \ + --config p/docker-compose \ + --config p/dockerfile \ + --config p/javascript \ + --config p/nextjs \ + --config p/nginx \ + --config p/nodejs \ + --config p/owasp-top-ten \ + --config p/python \ + --config p/r2c-security-audit \ + --config p/react \ + --config p/secrets \ + --config p/secure-defaults \ + --config p/security-audit \ + --config p/security-headers \ + --config p/sql-injection \ + --config p/terraform \ + --config p/typescript \ + --error \ + --skip-unknown-extensions \ + --timeout 10 \ + --timeout-threshold 3 \ + --text \ + --text-output=semgrep-security-report.txt \ . test: \ diff --git a/backend/Makefile b/backend/Makefile index 3b713cdab1..6a3b431c5a 100644 --- a/backend/Makefile +++ b/backend/Makefile @@ -157,26 +157,61 @@ 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 -# vars (defalts for Local dev) +# vars (defaults for Local dev) BACKEND_IMAGE_NAME ?= nest-backend-local TRIVY_EXIT_CODE ?= 0 +TRIVY_IMAGE_TAG := $$(grep -E '^FROM aquasec/trivy:' docker/trivy/Dockerfile | sed 's/^FROM //') -security-scan-backend-image: +backend-security-scan-image: @if [ "$(BACKEND_IMAGE_NAME)" = "nest-backend-local" ]; then \ $(MAKE) build-backend-local-image; \ fi - @echo "Scanning $(BACKEND_IMAGE_NAME)..." + @echo "Scanning Image: $(BACKEND_IMAGE_NAME)..." @docker run --rm \ -v /var/run/docker.sock:/var/run/docker.sock \ -v trivy-cache:/root/.cache/trivy \ - -v "$(CURDIR):/src" \ - -w /src \ - $$(grep -E '^FROM aquasec/trivy:' docker/trivy/Dockerfile | sed 's/^FROM //') \ + $(TRIVY_IMAGE_TAG) \ image \ - --config /src/trivy.yaml \ + --scanners vuln \ --exit-code $(TRIVY_EXIT_CODE) \ + --severity CRITICAL,HIGH \ + --no-progress \ $(BACKEND_IMAGE_NAME) +# For local +backend-security-scan-code: + @echo "Scanning Backend Code (Vulns + Config)..." + @docker run --rm \ + -v $(PWD)/backend:/app \ + -v trivy-cache:/root/.cache/trivy \ + $(TRIVY_IMAGE_TAG) \ + fs \ + --scanners vuln,config \ + --exit-code $(TRIVY_EXIT_CODE) \ + --severity CRITICAL,HIGH \ + --no-progress \ + /app + +# CI Only or Explicit Local Run +backend-security-scan-secrets: + @echo "Scanning Backend for Secrets..." + @docker run --rm \ + -v $(PWD)/backend:/app \ + -v trivy-cache:/root/.cache/trivy \ + $(TRIVY_IMAGE_TAG) \ + fs \ + --scanners secret \ + --exit-code $(TRIVY_EXIT_CODE) \ + --severity CRITICAL,HIGH \ + --no-progress \ + /app + +# local +backend-security-scan: backend-security-scan-code backend-security-scan-image + +# Full CI Scan +backend-security-scan-full: backend-security-scan backend-security-scan-secrets + shell-backend: @CMD="/bin/sh" $(MAKE) exec-backend-command-it diff --git a/docker/frontend/Dockerfile b/docker/frontend/Dockerfile index 4f829a760d..b5f87f2b9b 100644 --- a/docker/frontend/Dockerfile +++ b/docker/frontend/Dockerfile @@ -48,6 +48,11 @@ WORKDIR /app ENV NEXT_TELEMETRY_DISABLED=1 ENV NODE_ENV=production +ENV NPM_CACHE="/app/.npm" + +RUN --mount=type=cache,target=${NPM_CACHE} \ + npm install --ignore-scripts -g npm@latest --cache ${NPM_CACHE} && \ + npm cache clean --force # Fix CVE-2026-23745: Update npm's bundled tar to 7.5.3 in runner stage # Note: Must download tar with npm pack BEFORE removing the old tar (npm needs it) @@ -61,6 +66,18 @@ RUN cd /tmp && \ rm -rf package tar-7.5.7.tgz && \ grep -q 'version.*7.5.7' "${TAR_DIR}/package.json" +# Fix CVE-2025-64756: Update npm's bundled glob to 11.1.0 in runner stage +# Note: Must download glob with npm pack BEFORE removing the old glob (npm needs it) +RUN cd /tmp && \ + npm pack glob@11.1.0 && \ + tar -xzf glob-11.1.0.tgz && \ + GLOB_DIR="/usr/local/lib/node_modules/npm/node_modules/glob" && \ + rm -rf "${GLOB_DIR}" && \ + cp -r package "${GLOB_DIR}" && \ + chmod -R 755 "${GLOB_DIR}" && \ + rm -rf package glob-11.1.0.tgz && \ + grep -q 'version.*11.1.0' "${GLOB_DIR}/package.json" + RUN addgroup --system --gid 1001 nodejs && \ adduser --system --uid 1001 -G nodejs nextjs # Copying files with root as owner, so that executing user cannot change the container. diff --git a/frontend/Makefile b/frontend/Makefile index 6050eace64..69c73e83f6 100644 --- a/frontend/Makefile +++ b/frontend/Makefile @@ -59,23 +59,55 @@ generate-graphql-types: # Defaults for Local Development FRONTEND_IMAGE_NAME ?= nest-frontend-local TRIVY_EXIT_CODE ?= 0 +TRIVY_IMAGE_TAG := $$(grep -E '^FROM aquasec/trivy:' docker/trivy/Dockerfile | sed 's/^FROM //') -security-scan-frontend-image: +frontend-security-scan-image: @if [ "$(FRONTEND_IMAGE_NAME)" = "nest-frontend-local" ]; then \ $(MAKE) build-frontend-local-image; \ fi - @echo "Scanning $(FRONTEND_IMAGE_NAME)..." + @echo "Scanning Image: $(FRONTEND_IMAGE_NAME)..." @docker run --rm \ -v /var/run/docker.sock:/var/run/docker.sock \ -v trivy-cache:/root/.cache/trivy \ - -v "$(CURDIR):/src" \ - -w /src \ - $$(grep -E '^FROM aquasec/trivy:' docker/trivy/Dockerfile | sed 's/^FROM //') \ + $(TRIVY_IMAGE_TAG) \ image \ - --config /src/trivy.yaml \ + --scanners vuln \ --exit-code $(TRIVY_EXIT_CODE) \ + --severity CRITICAL,HIGH \ + --no-progress \ $(FRONTEND_IMAGE_NAME) +# local +frontend-security-scan-code: + @echo "Scanning Frontend Code (Vulns + Config)..." + @docker run --rm \ + -v $(PWD)/frontend:/app \ + -v trivy-cache:/root/.cache/trivy \ + $(TRIVY_IMAGE_TAG) \ + fs \ + --scanners vuln,config \ + --exit-code $(TRIVY_EXIT_CODE) \ + --severity CRITICAL,HIGH \ + --no-progress \ + /app + +# CI +frontend-security-scan-secrets: + @echo "Scanning Frontend for Secrets..." + @docker run --rm \ + -v $(PWD)/frontend:/app \ + -v trivy-cache:/root/.cache/trivy \ + $(TRIVY_IMAGE_TAG) \ + fs \ + --scanners secret \ + --exit-code $(TRIVY_EXIT_CODE) \ + --severity CRITICAL,HIGH \ + --no-progress \ + /app + +frontend-security-scan: frontend-security-scan-code frontend-security-scan-image +frontend-security-scan-full: frontend-security-scan frontend-security-scan-secrets + shell-frontend: @CMD="/bin/sh" $(MAKE) exec-frontend-command-it diff --git a/frontend/next.config.ts b/frontend/next.config.ts index ff4ca3667b..d91934a9a4 100644 --- a/frontend/next.config.ts +++ b/frontend/next.config.ts @@ -33,7 +33,7 @@ const nextConfig: NextConfig = { productionBrowserSourceMaps: true, serverExternalPackages: ['import-in-the-middle', 'require-in-the-middle'], transpilePackages: ['@react-leaflet/core', 'leaflet', 'react-leaflet', 'react-leaflet-cluster'], - ...(isLocal ? {} : { output: 'standalone' }), + output: 'standalone' , } export default withSentryConfig(nextConfig, { From 34a6b66d2989aae03be5e1f7f3ef6f2ac4a2e15f Mon Sep 17 00:00:00 2001 From: Muhammad Hassaan Saleem Date: Sun, 1 Feb 2026 23:58:01 +0500 Subject: [PATCH 11/17] Add dependabot tracking Signed-off-by: Muhammad Hassaan Saleem --- .github/dependabot.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 69c0abf597..f06dc48530 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -45,6 +45,11 @@ updates: schedule: interval: daily + - package-ecosystem: docker + directory: /docker/trivy + schedule: + interval: daily + - package-ecosystem: github-actions directory: / schedule: From 2075f0c422701dfc2a2985a8efcb8aa83cdd1784 Mon Sep 17 00:00:00 2001 From: Muhammad Hassaan Saleem Date: Mon, 2 Feb 2026 00:13:22 +0500 Subject: [PATCH 12/17] fix(docker): pin npm version and preserve build cache Signed-off-by: Muhammad Hassaan Saleem --- docker/frontend/Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docker/frontend/Dockerfile b/docker/frontend/Dockerfile index b5f87f2b9b..413ff24495 100644 --- a/docker/frontend/Dockerfile +++ b/docker/frontend/Dockerfile @@ -51,8 +51,7 @@ ENV NODE_ENV=production ENV NPM_CACHE="/app/.npm" RUN --mount=type=cache,target=${NPM_CACHE} \ - npm install --ignore-scripts -g npm@latest --cache ${NPM_CACHE} && \ - npm cache clean --force + npm install --ignore-scripts -g npm@10.9.0 --cache ${NPM_CACHE} # Fix CVE-2026-23745: Update npm's bundled tar to 7.5.3 in runner stage # Note: Must download tar with npm pack BEFORE removing the old tar (npm needs it) From 7be1e25b13a7773816f4c345ff296de1bc621744 Mon Sep 17 00:00:00 2001 From: Muhammad Hassaan Saleem Date: Tue, 3 Feb 2026 05:17:20 +0500 Subject: [PATCH 13/17] Update .github/workflows/run-ci-cd.yaml Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> --- .github/workflows/run-ci-cd.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/run-ci-cd.yaml b/.github/workflows/run-ci-cd.yaml index 98d91e6c3f..af51880625 100644 --- a/.github/workflows/run-ci-cd.yaml +++ b/.github/workflows/run-ci-cd.yaml @@ -152,10 +152,10 @@ jobs: - name: Run Trivy security scan run: | - make backend-security-scan-code - make frontend-security-scan-code - make backend-security-scan-secrets - make frontend-security-scan-secrets + make backend-security-scan-code TRIVY_EXIT_CODE=1 + make frontend-security-scan-code TRIVY_EXIT_CODE=1 + make backend-security-scan-secrets TRIVY_EXIT_CODE=1 + make frontend-security-scan-secrets TRIVY_EXIT_CODE=1 timeout-minutes: 5 run-backend-tests: From 5a4a9406418bc7a91f024e7bf5dfe92174f184e4 Mon Sep 17 00:00:00 2001 From: Muhammad Hassaan Saleem Date: Tue, 3 Feb 2026 05:25:03 +0500 Subject: [PATCH 14/17] ci: remove redundant trivy setup step Signed-off-by: Muhammad Hassaan Saleem --- .github/workflows/run-ci-cd.yaml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/run-ci-cd.yaml b/.github/workflows/run-ci-cd.yaml index 98d91e6c3f..778828b011 100644 --- a/.github/workflows/run-ci-cd.yaml +++ b/.github/workflows/run-ci-cd.yaml @@ -145,11 +145,6 @@ jobs: path: semgrep-security-report.txt retention-days: 14 - - name: Setup Trivy - uses: aquasecurity/setup-trivy@3fb12ec12f41e471780db15c232d5dd185dcb514 - with: - cache: true - - name: Run Trivy security scan run: | make backend-security-scan-code From dea9aae4954cc54bffab66cdb679804b01367f72 Mon Sep 17 00:00:00 2001 From: Muhammad Hassaan Saleem Date: Wed, 4 Feb 2026 23:52:51 +0500 Subject: [PATCH 15/17] fix(ci): optimize trivy scans and resolve build vulnerabilities Signed-off-by: Muhammad Hassaan Saleem --- .github/workflows/run-ci-cd.yaml | 8 ++-- Makefile | 6 --- backend/Makefile | 72 +++++++++++++++----------------- docker/frontend/Dockerfile | 19 ++------- frontend/Makefile | 39 ++++++++--------- frontend/next.config.ts | 3 +- trivy.yaml | 2 +- trivyignore.yaml | 4 ++ 8 files changed, 63 insertions(+), 90 deletions(-) diff --git a/.github/workflows/run-ci-cd.yaml b/.github/workflows/run-ci-cd.yaml index 501b0c3030..c9b8993fed 100644 --- a/.github/workflows/run-ci-cd.yaml +++ b/.github/workflows/run-ci-cd.yaml @@ -144,13 +144,11 @@ jobs: name: semgrep-results-run-${{ github.run_number }} path: semgrep-security-report.txt retention-days: 14 - + # semgrep shouldnot run again - name: Run Trivy security scan run: | - make backend-security-scan-code TRIVY_EXIT_CODE=1 - make frontend-security-scan-code TRIVY_EXIT_CODE=1 - make backend-security-scan-secrets TRIVY_EXIT_CODE=1 - make frontend-security-scan-secrets TRIVY_EXIT_CODE=1 + make backend-security-scan-ci TRIVY_EXIT_CODE=1 + make frontend-security-scan-ci TRIVY_EXIT_CODE=1 timeout-minutes: 5 run-backend-tests: diff --git a/Makefile b/Makefile index 2fa2e7a46a..3347a9b82e 100644 --- a/Makefile +++ b/Makefile @@ -62,12 +62,6 @@ security-scan: \ backend-security-scan \ frontend-security-scan -# CI/CD full Scan -security-scan-full: \ - security-scan \ - backend-security-scan-secrets \ - frontend-security-scan-secrets - security-scan-code-semgrep: @echo "Running Semgrep security scan..." @docker run --rm \ diff --git a/backend/Makefile b/backend/Makefile index 6a3b431c5a..e1ae7c6b7f 100644 --- a/backend/Makefile +++ b/backend/Makefile @@ -168,49 +168,43 @@ backend-security-scan-image: fi @echo "Scanning Image: $(BACKEND_IMAGE_NAME)..." @docker run --rm \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v trivy-cache:/root/.cache/trivy \ - $(TRIVY_IMAGE_TAG) \ - image \ - --scanners vuln \ - --exit-code $(TRIVY_EXIT_CODE) \ - --severity CRITICAL,HIGH \ - --no-progress \ - $(BACKEND_IMAGE_NAME) - -# For local + -v /var/run/docker.sock:/var/run/docker.sock \ + -v $(PWD)/trivy.yaml:/trivy.yaml:ro \ + -v $(PWD)/trivyignore.yaml:/trivyignore.yaml:ro \ + -v trivy-cache:/root/.cache/trivy \ + -e TRIVY_SCANNERS \ + $(TRIVY_IMAGE_TAG) \ + image \ + --config /trivy.yaml \ + --exit-code $(TRIVY_EXIT_CODE) \ + --no-progress \ + $(BACKEND_IMAGE_NAME) + backend-security-scan-code: - @echo "Scanning Backend Code (Vulns + Config)..." - @docker run --rm \ - -v $(PWD)/backend:/app \ - -v trivy-cache:/root/.cache/trivy \ - $(TRIVY_IMAGE_TAG) \ - fs \ - --scanners vuln,config \ - --exit-code $(TRIVY_EXIT_CODE) \ - --severity CRITICAL,HIGH \ - --no-progress \ - /app - -# CI Only or Explicit Local Run -backend-security-scan-secrets: - @echo "Scanning Backend for Secrets..." + @echo "Scanning Backend Code..." @docker run --rm \ - -v $(PWD)/backend:/app \ - -v trivy-cache:/root/.cache/trivy \ - $(TRIVY_IMAGE_TAG) \ - fs \ - --scanners secret \ - --exit-code $(TRIVY_EXIT_CODE) \ - --severity CRITICAL,HIGH \ - --no-progress \ - /app + -v $(PWD)/backend:/app \ + -v $(PWD)/trivy.yaml:/trivy.yaml:ro \ + -v $(PWD)/trivyignore.yaml:/trivyignore.yaml:ro \ + -v trivy-cache:/root/.cache/trivy \ + -e TRIVY_SCANNERS \ + $(TRIVY_IMAGE_TAG) \ + fs \ + --config /trivy.yaml \ + --exit-code $(TRIVY_EXIT_CODE) \ + --no-progress \ + /app # local -backend-security-scan: backend-security-scan-code backend-security-scan-image - -# Full CI Scan -backend-security-scan-full: backend-security-scan backend-security-scan-secrets +backend-security-scan: + @echo "Running LOCAL security scan (vuln + config only)" + @TRIVY_SCANNERS=vuln,misconfig \ + $(MAKE) backend-security-scan-code backend-security-scan-image + +# full (TRIVY_SCANNERS=vuln,misconfig,secret) when not set +backend-security-scan-ci: + @echo "Running CI backend security scan (vuln + config + secret)" + $(MAKE) backend-security-scan-code backend-security-scan-image shell-backend: @CMD="/bin/sh" $(MAKE) exec-backend-command-it diff --git a/docker/frontend/Dockerfile b/docker/frontend/Dockerfile index 413ff24495..ec7cfc7b93 100644 --- a/docker/frontend/Dockerfile +++ b/docker/frontend/Dockerfile @@ -33,6 +33,9 @@ COPY --chmod=444 .env .pnpmrc next.config.ts postcss.config.js tailwind.config.m COPY --chmod=555 public public COPY --chmod=555 src src +ARG FORCE_STANDALONE +ENV FORCE_STANDALONE=$FORCE_STANDALONE + # Next.js collects completely anonymous telemetry data about general usage. # Learn more here: https://nextjs.org/telemetry ENV NEXT_TELEMETRY_DISABLED=1 @@ -48,10 +51,6 @@ WORKDIR /app ENV NEXT_TELEMETRY_DISABLED=1 ENV NODE_ENV=production -ENV NPM_CACHE="/app/.npm" - -RUN --mount=type=cache,target=${NPM_CACHE} \ - npm install --ignore-scripts -g npm@10.9.0 --cache ${NPM_CACHE} # Fix CVE-2026-23745: Update npm's bundled tar to 7.5.3 in runner stage # Note: Must download tar with npm pack BEFORE removing the old tar (npm needs it) @@ -65,18 +64,6 @@ RUN cd /tmp && \ rm -rf package tar-7.5.7.tgz && \ grep -q 'version.*7.5.7' "${TAR_DIR}/package.json" -# Fix CVE-2025-64756: Update npm's bundled glob to 11.1.0 in runner stage -# Note: Must download glob with npm pack BEFORE removing the old glob (npm needs it) -RUN cd /tmp && \ - npm pack glob@11.1.0 && \ - tar -xzf glob-11.1.0.tgz && \ - GLOB_DIR="/usr/local/lib/node_modules/npm/node_modules/glob" && \ - rm -rf "${GLOB_DIR}" && \ - cp -r package "${GLOB_DIR}" && \ - chmod -R 755 "${GLOB_DIR}" && \ - rm -rf package glob-11.1.0.tgz && \ - grep -q 'version.*11.1.0' "${GLOB_DIR}/package.json" - RUN addgroup --system --gid 1001 nodejs && \ adduser --system --uid 1001 -G nodejs nextjs # Copying files with root as owner, so that executing user cannot change the container. diff --git a/frontend/Makefile b/frontend/Makefile index 69c73e83f6..29749afe2e 100644 --- a/frontend/Makefile +++ b/frontend/Makefile @@ -2,6 +2,7 @@ SHELL := /bin/bash build-frontend-local-image: @DOCKER_BUILDKIT=1 NEXT_PUBLIC_ENVIRONMENT=local docker build \ + --build-arg FORCE_STANDALONE=true \ --no-cache \ -f docker/frontend/Dockerfile \ -t nest-frontend-local \ @@ -56,7 +57,6 @@ 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)) -# Defaults for Local Development FRONTEND_IMAGE_NAME ?= nest-frontend-local TRIVY_EXIT_CODE ?= 0 TRIVY_IMAGE_TAG := $$(grep -E '^FROM aquasec/trivy:' docker/trivy/Dockerfile | sed 's/^FROM //') @@ -68,45 +68,40 @@ frontend-security-scan-image: @echo "Scanning Image: $(FRONTEND_IMAGE_NAME)..." @docker run --rm \ -v /var/run/docker.sock:/var/run/docker.sock \ + -v $(PWD)/trivy.yaml:/trivy.yaml:ro \ + -v $(PWD)/trivyignore.yaml:/trivyignore.yaml:ro \ -v trivy-cache:/root/.cache/trivy \ + -e TRIVY_SCANNERS \ $(TRIVY_IMAGE_TAG) \ image \ - --scanners vuln \ + --config trivy.yaml \ --exit-code $(TRIVY_EXIT_CODE) \ - --severity CRITICAL,HIGH \ --no-progress \ $(FRONTEND_IMAGE_NAME) -# local frontend-security-scan-code: - @echo "Scanning Frontend Code (Vulns + Config)..." + @echo "Scanning Frontend Code..." @docker run --rm \ -v $(PWD)/frontend:/app \ -v trivy-cache:/root/.cache/trivy \ + -v $(PWD)/trivyignore.yaml:/trivyignore.yaml:ro \ + -v $(PWD)/trivy.yaml:/trivy.yaml:ro \ + -e TRIVY_SCANNERS \ $(TRIVY_IMAGE_TAG) \ fs \ - --scanners vuln,config \ + --config trivy.yaml \ --exit-code $(TRIVY_EXIT_CODE) \ - --severity CRITICAL,HIGH \ --no-progress \ /app -# CI -frontend-security-scan-secrets: - @echo "Scanning Frontend for Secrets..." - @docker run --rm \ - -v $(PWD)/frontend:/app \ - -v trivy-cache:/root/.cache/trivy \ - $(TRIVY_IMAGE_TAG) \ - fs \ - --scanners secret \ - --exit-code $(TRIVY_EXIT_CODE) \ - --severity CRITICAL,HIGH \ - --no-progress \ - /app +frontend-security-scan: + @echo "Running LOCAL frontend security scan (vuln + config only)" + @TRIVY_SCANNERS=vuln,misconfig \ + $(MAKE) frontend-security-scan-code frontend-security-scan-image -frontend-security-scan: frontend-security-scan-code frontend-security-scan-image -frontend-security-scan-full: frontend-security-scan frontend-security-scan-secrets +frontend-security-scan-ci: + @echo "Running CI frontend security scan (vuln + config + secret)" + $(MAKE) frontend-security-scan-code frontend-security-scan-image shell-frontend: @CMD="/bin/sh" $(MAKE) exec-frontend-command-it diff --git a/frontend/next.config.ts b/frontend/next.config.ts index d91934a9a4..813581bddf 100644 --- a/frontend/next.config.ts +++ b/frontend/next.config.ts @@ -2,6 +2,7 @@ import { withSentryConfig } from '@sentry/nextjs' import type { NextConfig } from 'next' const isLocal = process.env.NEXT_PUBLIC_ENVIRONMENT === 'local' +const forceStandalone = process.env.FORCE_STANDALONE === 'true'; const nextConfig: NextConfig = { devIndicators: false, @@ -33,7 +34,7 @@ const nextConfig: NextConfig = { productionBrowserSourceMaps: true, serverExternalPackages: ['import-in-the-middle', 'require-in-the-middle'], transpilePackages: ['@react-leaflet/core', 'leaflet', 'react-leaflet', 'react-leaflet-cluster'], - output: 'standalone' , + ...(isLocal && !forceStandalone ? {} : { output: 'standalone' }), } export default withSentryConfig(nextConfig, { diff --git a/trivy.yaml b/trivy.yaml index 54725c937e..5b1656c7db 100644 --- a/trivy.yaml +++ b/trivy.yaml @@ -18,6 +18,6 @@ timeout: 10m vulnerability: ignore-unfixed: true security-checks: - - config + - misconfig - secret - vuln diff --git a/trivyignore.yaml b/trivyignore.yaml index 3bd882cadc..cc82d2ed94 100644 --- a/trivyignore.yaml +++ b/trivyignore.yaml @@ -1,3 +1,7 @@ vulnerabilities: # TODO(arkid15r): Remove when v5.9.3 is no longer current. - id: CVE-2025-64756 # glob: Command Injection Vulnerability via Malicious Filenames. + - id: CVE-2024-21538 # cross-spawn: Regular expression denial of service (High) + - id: CVE-2026-23745 # node-tar: Arbitrary file overwrite and symlink poisoning (High) + - id: CVE-2026-23950 # node-tar: Arbitrary file overwrite via Unicode path collision (High) + - id: CVE-2026-24842 # node-tar: Arbitrary file creation via path traversal (High) \ No newline at end of file From 96aab6ea0ea31a17be1b448077bd04e3de384ab2 Mon Sep 17 00:00:00 2001 From: Muhammad Hassaan Saleem Date: Thu, 5 Feb 2026 00:32:49 +0500 Subject: [PATCH 16/17] Update trivy.yaml to not use depracted syntax Signed-off-by: Muhammad Hassaan Saleem --- .github/workflows/run-ci-cd.yaml | 2 +- trivy.yaml | 8 ++++---- trivyignore.yaml | 24 ++++++++++++++++++++---- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/.github/workflows/run-ci-cd.yaml b/.github/workflows/run-ci-cd.yaml index c9b8993fed..a50a0c7b5b 100644 --- a/.github/workflows/run-ci-cd.yaml +++ b/.github/workflows/run-ci-cd.yaml @@ -144,7 +144,7 @@ jobs: name: semgrep-results-run-${{ github.run_number }} path: semgrep-security-report.txt retention-days: 14 - # semgrep shouldnot run again + # semgrep should not un again - name: Run Trivy security scan run: | make backend-security-scan-ci TRIVY_EXIT_CODE=1 diff --git a/trivy.yaml b/trivy.yaml index 5b1656c7db..2e2963c158 100644 --- a/trivy.yaml +++ b/trivy.yaml @@ -5,6 +5,10 @@ ignorefile: trivyignore.yaml scan: skip-files: + scanners: + - misconfig + - secret + - vuln severity: - CRITICAL @@ -17,7 +21,3 @@ timeout: 10m vulnerability: ignore-unfixed: true - security-checks: - - misconfig - - secret - - vuln diff --git a/trivyignore.yaml b/trivyignore.yaml index cc82d2ed94..3f321ac999 100644 --- a/trivyignore.yaml +++ b/trivyignore.yaml @@ -1,7 +1,23 @@ vulnerabilities: # TODO(arkid15r): Remove when v5.9.3 is no longer current. - id: CVE-2025-64756 # glob: Command Injection Vulnerability via Malicious Filenames. - - id: CVE-2024-21538 # cross-spawn: Regular expression denial of service (High) - - id: CVE-2026-23745 # node-tar: Arbitrary file overwrite and symlink poisoning (High) - - id: CVE-2026-23950 # node-tar: Arbitrary file overwrite via Unicode path collision (High) - - id: CVE-2026-24842 # node-tar: Arbitrary file creation via path traversal (High) \ No newline at end of file +# ------------------------------------------------------------------------- +# Frontend Dependencies (TODO: Fix in separate PR) +# Scope: These require package.json updates which are out of scope for this CI/CD PR. +# ------------------------------------------------------------------------- + +# cross-spawn: Regular expression denial of service (High) +# https://avd.aquasec.com/nvd/cve-2024-21538 + - id: CVE-2024-21538 + +# node-tar: Arbitrary file overwrite and symlink poisoning (High) +# https://avd.aquasec.com/nvd/cve-2026-23745 + - id: CVE-2026-23745 + +# node-tar: Arbitrary file overwrite via Unicode path collision (High) +# https://avd.aquasec.com/nvd/cve-2026-23950 + - id: CVE-2026-23950 + +# node-tar: Arbitrary file creation via path traversal (High) +# https://avd.aquasec.com/nvd/cve-2026-24842 + - id: CVE-2026-24842 \ No newline at end of file From 8c0cf8b2d4dd8d48e2db6df2414e0225db1d0d5e Mon Sep 17 00:00:00 2001 From: Arkadii Yakovets Date: Wed, 4 Feb 2026 22:09:48 -0800 Subject: [PATCH 17/17] Update code --- .github/workflows/run-ci-cd.yaml | 49 +++++++-------- .gitignore | 1 + Makefile | 100 ++++++++++++++++++++----------- backend/Makefile | 54 ++++------------- cspell/Makefile | 7 ++- cspell/custom-dict.txt | 2 + frontend/Makefile | 52 ++++------------ frontend/next.config.ts | 2 +- trivy.yaml | 13 ++-- trivyignore.yaml | 26 ++------ 10 files changed, 133 insertions(+), 173 deletions(-) diff --git a/.github/workflows/run-ci-cd.yaml b/.github/workflows/run-ci-cd.yaml index a50a0c7b5b..3c4b1b8cbc 100644 --- a/.github/workflows/run-ci-cd.yaml +++ b/.github/workflows/run-ci-cd.yaml @@ -137,18 +137,15 @@ jobs: - name: Run Semgrep security scan run: make security-scan-code-semgrep - - name: Upload Semgrep report - if: always() - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f + - name: Cache Trivy DB + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 with: - name: semgrep-results-run-${{ github.run_number }} - path: semgrep-security-report.txt - retention-days: 14 - # semgrep should not un again + path: .trivy-cache + key: trivy-${{ runner.os }}-${{ hashFiles('docker/trivy/Dockerfile') }} + restore-keys: trivy-${{ runner.os }}- + - name: Run Trivy security scan - run: | - make backend-security-scan-ci TRIVY_EXIT_CODE=1 - make frontend-security-scan-ci TRIVY_EXIT_CODE=1 + run: make security-scan-code-trivy SCANNERS=misconfig,secret,vuln timeout-minutes: 5 run-backend-tests: @@ -544,15 +541,17 @@ jobs: - name: Check out repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + - name: Cache Trivy DB + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 + with: + path: .trivy-cache + key: trivy-${{ runner.os }}-${{ hashFiles('docker/trivy/Dockerfile') }} + restore-keys: trivy-${{ runner.os }}- + - name: Run Trivy security scan via Makefile run: | - make backend-security-scan-image \ - BACKEND_IMAGE_NAME=owasp/nest:backend-staging \ - TRIVY_EXIT_CODE=1 - - make frontend-security-scan-image \ - FRONTEND_IMAGE_NAME=owasp/nest:frontend-staging \ - TRIVY_EXIT_CODE=1 + make security-scan-backend-image BACKEND_IMAGE_NAME=owasp/nest:backend-staging + make security-scan-frontend-image FRONTEND_IMAGE_NAME=owasp/nest:frontend-staging timeout-minutes: 5 deploy-staging-nest: @@ -901,15 +900,17 @@ jobs: - name: Check out repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + - name: Cache Trivy DB + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 + with: + path: .trivy-cache + key: trivy-${{ runner.os }}-${{ hashFiles('docker/trivy/Dockerfile') }} + restore-keys: trivy-${{ runner.os }}- + - name: Run Trivy security scan via Makefile run: | - make backend-security-scan-image \ - BACKEND_IMAGE_NAME=owasp/nest:backend-production \ - TRIVY_EXIT_CODE=1 - - make frontend-security-scan-image \ - FRONTEND_IMAGE_NAME=owasp/nest:frontend-production \ - TRIVY_EXIT_CODE=1 + make security-scan-backend-image BACKEND_IMAGE_NAME=owasp/nest:backend-production + make security-scan-frontend-image FRONTEND_IMAGE_NAME=owasp/nest:frontend-production timeout-minutes: 5 deploy-production-nest: diff --git a/.gitignore b/.gitignore index 599822145d..2c73948f38 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ backend/fuzzing_results/ .python_history .python-version .ruff_cache +.trivy-cache .venv/ .vscode *.bak diff --git a/Makefile b/Makefile index 3347a9b82e..0527fabe30 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,10 @@ include cspell/Makefile include docs/Makefile include frontend/Makefile -.PHONY: build clean check pre-commit prune run scan-images security-scan test update +.PHONY: build clean check pre-commit prune run scan-images security-scan security-scan-code \ + security-scan-code-semgrep security-scan-code-trivy security-scan-images \ + security-scan-backend-image security-scan-frontend-image test update \ + clean-trivy-cache MAKEFLAGS += --no-print-directory @@ -12,7 +15,8 @@ build: clean: \ clean-dependencies \ - clean-docker + clean-docker \ + clean-trivy-cache clean-dependencies: \ clean-backend-dependencies \ @@ -23,6 +27,9 @@ clean-docker: \ clean-docs-docker \ clean-frontend-docker +clean-trivy-cache: + @rm -rf $(CURDIR)/.trivy-cache + check: \ check-spelling \ check-backend \ @@ -56,49 +63,70 @@ 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 -# Default Local Safe Scan NO Secrets security-scan: \ + security-scan-code \ + security-scan-images + +security-scan-code: \ security-scan-code-semgrep \ - backend-security-scan \ - frontend-security-scan + 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 \ + @docker run \ + --rm \ -v "$(PWD):/src" \ -w /src \ $$(grep -E '^FROM semgrep/semgrep:' docker/semgrep/Dockerfile | sed 's/^FROM //') \ semgrep \ - --config p/ci \ - --config p/command-injection \ - --config p/cwe-top-25 \ - --config p/default \ - --config p/django \ - --config p/docker \ - --config p/docker-compose \ - --config p/dockerfile \ - --config p/javascript \ - --config p/nextjs \ - --config p/nginx \ - --config p/nodejs \ - --config p/owasp-top-ten \ - --config p/python \ - --config p/r2c-security-audit \ - --config p/react \ - --config p/secrets \ - --config p/secure-defaults \ - --config p/security-audit \ - --config p/security-headers \ - --config p/sql-injection \ - --config p/terraform \ - --config p/typescript \ - --error \ - --skip-unknown-extensions \ - --timeout 10 \ - --timeout-threshold 3 \ - --text \ - --text-output=semgrep-security-report.txt \ - . + --config p/ci \ + --config p/command-injection \ + --config p/cwe-top-25 \ + --config p/default \ + --config p/django \ + --config p/docker \ + --config p/docker-compose \ + --config p/dockerfile \ + --config p/javascript \ + --config p/nextjs \ + --config p/nginx \ + --config p/nodejs \ + --config p/owasp-top-ten \ + --config p/python \ + --config p/r2c-security-audit \ + --config p/react \ + --config p/secrets \ + --config p/secure-defaults \ + --config p/security-audit \ + --config p/security-headers \ + --config p/sql-injection \ + --config p/terraform \ + --config p/typescript \ + --error \ + --skip-unknown-extensions \ + --timeout 10 \ + --timeout-threshold 3 \ + --text \ + --text-output=semgrep-security-report.txt \ + . + +SCANNERS ?= misconfig,vuln + +security-scan-code-trivy: + @echo "Running Trivy security scan..." + @docker run \ + --rm \ + -e TRIVY_SCANNERS="$(SCANNERS)" \ + -v $(CURDIR):/src \ + -v $(CURDIR)/trivyignore.yaml:/trivyignore.yaml:ro \ + -v $(CURDIR)/trivy.yaml:/trivy.yaml:ro \ + -v $(CURDIR)/.trivy-cache:/root/.cache/trivy \ + $$(grep -E '^FROM aquasec/trivy:' docker/trivy/Dockerfile | sed 's/^FROM //') \ + fs --config /trivy.yaml /src test: \ test-nest-app diff --git a/backend/Makefile b/backend/Makefile index e1ae7c6b7f..4479a0ccbf 100644 --- a/backend/Makefile +++ b/backend/Makefile @@ -157,54 +157,24 @@ 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 -# vars (defaults for Local dev) +# vars (defaults for local dev) BACKEND_IMAGE_NAME ?= nest-backend-local -TRIVY_EXIT_CODE ?= 0 -TRIVY_IMAGE_TAG := $$(grep -E '^FROM aquasec/trivy:' docker/trivy/Dockerfile | sed 's/^FROM //') +IMAGE_SCANNERS ?= misconfig,secret,vuln -backend-security-scan-image: +security-scan-backend-image: @if [ "$(BACKEND_IMAGE_NAME)" = "nest-backend-local" ]; then \ $(MAKE) build-backend-local-image; \ fi - @echo "Scanning Image: $(BACKEND_IMAGE_NAME)..." - @docker run --rm \ + @echo "Scanning image: $(BACKEND_IMAGE_NAME)..." + @docker run \ + --rm \ + -e TRIVY_SCANNERS="$(IMAGE_SCANNERS)" \ + -v $(CURDIR)/trivyignore.yaml:/trivyignore.yaml:ro \ -v /var/run/docker.sock:/var/run/docker.sock \ - -v $(PWD)/trivy.yaml:/trivy.yaml:ro \ - -v $(PWD)/trivyignore.yaml:/trivyignore.yaml:ro \ - -v trivy-cache:/root/.cache/trivy \ - -e TRIVY_SCANNERS \ - $(TRIVY_IMAGE_TAG) \ - image \ - --config /trivy.yaml \ - --exit-code $(TRIVY_EXIT_CODE) \ - --no-progress \ - $(BACKEND_IMAGE_NAME) - -backend-security-scan-code: - @echo "Scanning Backend Code..." - @docker run --rm \ - -v $(PWD)/backend:/app \ - -v $(PWD)/trivy.yaml:/trivy.yaml:ro \ - -v $(PWD)/trivyignore.yaml:/trivyignore.yaml:ro \ - -v trivy-cache:/root/.cache/trivy \ - -e TRIVY_SCANNERS \ - $(TRIVY_IMAGE_TAG) \ - fs \ - --config /trivy.yaml \ - --exit-code $(TRIVY_EXIT_CODE) \ - --no-progress \ - /app - -# local -backend-security-scan: - @echo "Running LOCAL security scan (vuln + config only)" - @TRIVY_SCANNERS=vuln,misconfig \ - $(MAKE) backend-security-scan-code backend-security-scan-image - -# full (TRIVY_SCANNERS=vuln,misconfig,secret) when not set -backend-security-scan-ci: - @echo "Running CI backend security scan (vuln + config + secret)" - $(MAKE) backend-security-scan-code backend-security-scan-image + -v $(CURDIR)/trivy.yaml:/trivy.yaml:ro \ + -v $(CURDIR)/.trivy-cache:/root/.cache/trivy \ + $$(grep -E '^FROM aquasec/trivy:' docker/trivy/Dockerfile | sed 's/^FROM //') \ + image --config /trivy.yaml $(BACKEND_IMAGE_NAME) shell-backend: @CMD="/bin/sh" $(MAKE) exec-backend-command-it diff --git a/cspell/Makefile b/cspell/Makefile index 04ac58e60a..f4053feb27 100644 --- a/cspell/Makefile +++ b/cspell/Makefile @@ -17,9 +17,10 @@ cspell-run: update-cspell-dependencies: cspell-install @-docker run \ - -it \ - --mount type=bind,src="$(CURDIR)",dst=/nest \ --entrypoint=/bin/sh \ - --workdir=/nest/cspell \ + --interactive \ + --mount type=bind,src="$(CURDIR)",dst=/nest \ --rm \ + --tty \ + --workdir=/nest/cspell \ cspell -c "pnpm install && pnpm upgrade && rm -rf ./node_modules" diff --git a/cspell/custom-dict.txt b/cspell/custom-dict.txt index b9e083a6a1..8fbc88f985 100644 --- a/cspell/custom-dict.txt +++ b/cspell/custom-dict.txt @@ -1,3 +1,4 @@ +AVD Agentic Agsoc Aichi @@ -127,6 +128,7 @@ menteemodule_set mentees mern millify +misconfig mkv mpim navlink diff --git a/frontend/Makefile b/frontend/Makefile index 29749afe2e..b81ffb42be 100644 --- a/frontend/Makefile +++ b/frontend/Makefile @@ -2,7 +2,7 @@ SHELL := /bin/bash build-frontend-local-image: @DOCKER_BUILDKIT=1 NEXT_PUBLIC_ENVIRONMENT=local docker build \ - --build-arg FORCE_STANDALONE=true \ + --build-arg FORCE_STANDALONE=yes \ --no-cache \ -f docker/frontend/Dockerfile \ -t nest-frontend-local \ @@ -58,50 +58,22 @@ generate-graphql-types: && pnpm run graphql-codegen)) FRONTEND_IMAGE_NAME ?= nest-frontend-local -TRIVY_EXIT_CODE ?= 0 -TRIVY_IMAGE_TAG := $$(grep -E '^FROM aquasec/trivy:' docker/trivy/Dockerfile | sed 's/^FROM //') +IMAGE_SCANNERS ?= misconfig,secret,vuln -frontend-security-scan-image: +security-scan-frontend-image: @if [ "$(FRONTEND_IMAGE_NAME)" = "nest-frontend-local" ]; then \ $(MAKE) build-frontend-local-image; \ fi - @echo "Scanning Image: $(FRONTEND_IMAGE_NAME)..." - @docker run --rm \ + @echo "Scanning image: $(FRONTEND_IMAGE_NAME)..." + @docker run \ + --rm \ + -e TRIVY_SCANNERS="$(IMAGE_SCANNERS)" \ -v /var/run/docker.sock:/var/run/docker.sock \ - -v $(PWD)/trivy.yaml:/trivy.yaml:ro \ - -v $(PWD)/trivyignore.yaml:/trivyignore.yaml:ro \ - -v trivy-cache:/root/.cache/trivy \ - -e TRIVY_SCANNERS \ - $(TRIVY_IMAGE_TAG) \ - image \ - --config trivy.yaml \ - --exit-code $(TRIVY_EXIT_CODE) \ - --no-progress \ - $(FRONTEND_IMAGE_NAME) - -frontend-security-scan-code: - @echo "Scanning Frontend Code..." - @docker run --rm \ - -v $(PWD)/frontend:/app \ - -v trivy-cache:/root/.cache/trivy \ - -v $(PWD)/trivyignore.yaml:/trivyignore.yaml:ro \ - -v $(PWD)/trivy.yaml:/trivy.yaml:ro \ - -e TRIVY_SCANNERS \ - $(TRIVY_IMAGE_TAG) \ - fs \ - --config trivy.yaml \ - --exit-code $(TRIVY_EXIT_CODE) \ - --no-progress \ - /app - -frontend-security-scan: - @echo "Running LOCAL frontend security scan (vuln + config only)" - @TRIVY_SCANNERS=vuln,misconfig \ - $(MAKE) frontend-security-scan-code frontend-security-scan-image - -frontend-security-scan-ci: - @echo "Running CI frontend security scan (vuln + config + secret)" - $(MAKE) frontend-security-scan-code frontend-security-scan-image + -v $(CURDIR)/trivy.yaml:/trivy.yaml:ro \ + -v $(CURDIR)/trivyignore.yaml:/trivyignore.yaml:ro \ + -v $(CURDIR)/.trivy-cache:/root/.cache/trivy \ + $$(grep -E '^FROM aquasec/trivy:' docker/trivy/Dockerfile | sed 's/^FROM //') \ + image --config /trivy.yaml $(FRONTEND_IMAGE_NAME) shell-frontend: @CMD="/bin/sh" $(MAKE) exec-frontend-command-it diff --git a/frontend/next.config.ts b/frontend/next.config.ts index 813581bddf..94eb3a2bd0 100644 --- a/frontend/next.config.ts +++ b/frontend/next.config.ts @@ -1,8 +1,8 @@ import { withSentryConfig } from '@sentry/nextjs' import type { NextConfig } from 'next' +const forceStandalone = process.env.FORCE_STANDALONE === 'yes' const isLocal = process.env.NEXT_PUBLIC_ENVIRONMENT === 'local' -const forceStandalone = process.env.FORCE_STANDALONE === 'true'; const nextConfig: NextConfig = { devIndicators: false, diff --git a/trivy.yaml b/trivy.yaml index 2e2963c158..c8cd815d2b 100644 --- a/trivy.yaml +++ b/trivy.yaml @@ -1,22 +1,21 @@ +exit-code: 1 + filesystem: skip-files: -ignorefile: trivyignore.yaml +ignorefile: /trivyignore.yaml + +report: all scan: + show-suppressed: true skip-files: - scanners: - - misconfig - - secret - - vuln severity: - CRITICAL - HIGH - UNKNOWN -show-suppressed: true - timeout: 10m vulnerability: diff --git a/trivyignore.yaml b/trivyignore.yaml index 3f321ac999..8e1f123b9d 100644 --- a/trivyignore.yaml +++ b/trivyignore.yaml @@ -1,23 +1,9 @@ +misconfigurations: + - id: AVD-DS-0002 # Require non-root USER in Dockerfile. + paths: + - docker/semgrep/Dockerfile + - docker/trivy/Dockerfile + vulnerabilities: # TODO(arkid15r): Remove when v5.9.3 is no longer current. - id: CVE-2025-64756 # glob: Command Injection Vulnerability via Malicious Filenames. -# ------------------------------------------------------------------------- -# Frontend Dependencies (TODO: Fix in separate PR) -# Scope: These require package.json updates which are out of scope for this CI/CD PR. -# ------------------------------------------------------------------------- - -# cross-spawn: Regular expression denial of service (High) -# https://avd.aquasec.com/nvd/cve-2024-21538 - - id: CVE-2024-21538 - -# node-tar: Arbitrary file overwrite and symlink poisoning (High) -# https://avd.aquasec.com/nvd/cve-2026-23745 - - id: CVE-2026-23745 - -# node-tar: Arbitrary file overwrite via Unicode path collision (High) -# https://avd.aquasec.com/nvd/cve-2026-23950 - - id: CVE-2026-23950 - -# node-tar: Arbitrary file creation via path traversal (High) -# https://avd.aquasec.com/nvd/cve-2026-24842 - - id: CVE-2026-24842 \ No newline at end of file