From b1611cd7e1ec69be56882200a798c3c8ca141929 Mon Sep 17 00:00:00 2001 From: Baivab Sarkar <109382325+ThisIs-Developer@users.noreply.github.com> Date: Sun, 15 Nov 2026 17:46:59 +0530 Subject: [PATCH 1/4] fix(docker): use slim patched Alpine Nginx runtime --- Dockerfile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index bc7c50b4..af415415 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,9 @@ # Use nginx as the base image for serving static files -FROM nginx:alpine +FROM nginx:1.31.8-alpine3.24-slim + +# Omit optional Alpine/Nginx modules to reduce third-party package exposure. +# Apply security updates from the supported Alpine stable release. +RUN apk upgrade --no-cache # PERF-019: Only copy necessary web files (exclude .git, desktop-app, wiki, etc.) COPY index.html /usr/share/nginx/html/ From 8274cc6bbbe8e012408fd2400c6667ddebce52b6 Mon Sep 17 00:00:00 2001 From: Baivab Sarkar <109382325+ThisIs-Developer@users.noreply.github.com> Date: Sun, 15 Nov 2026 17:47:02 +0530 Subject: [PATCH 2/4] ci(docker): smoke-test HTTP and report image vulnerabilities --- .github/workflows/docker-publish.yml | 50 ++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index ae6ec091..30b85082 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -42,10 +42,60 @@ jobs: type=sha,prefix=sha- type=raw,value=latest,enable={{is_default_branch}} + # Test the same minimal HTTP-only Docker application; no TLS setup is added. + - name: Build fresh Docker image for security testing + run: docker build --pull -t markdown-viewer:security-audit . + + - name: Smoke-test HTTP application and Nginx configuration + run: | + docker run -d --rm --name mdv-security-test -p 127.0.0.1:18080:80 markdown-viewer:security-audit + trap 'docker stop mdv-security-test >/dev/null 2>&1 || true' EXIT + docker exec mdv-security-test nginx -t + for i in $(seq 1 30); do + if curl -fsS --max-time 3 -o /dev/null http://127.0.0.1:18080/; then break; fi + sleep 1 + done + curl -fsS --max-time 10 -o /dev/null http://127.0.0.1:18080/ + curl -fsS --max-time 10 -o /dev/null http://127.0.0.1:18080/styles.css + curl -fsS --max-time 10 -o /dev/null http://127.0.0.1:18080/script.js + curl -fsSI --max-time 10 http://127.0.0.1:18080/ | grep -qi '^content-security-policy:' + ! curl -fsSI --max-time 10 http://127.0.0.1:18080/ | grep -qi 'upgrade-insecure-requests' + + - name: Scan all known OS and library CVEs (machine-readable artifact) + uses: aquasecurity/trivy-action@v0.36.0 + with: + image-ref: markdown-viewer:security-audit + format: json + output: docker-artifacts/trivy-vulnerabilities.json + scanners: vuln + vuln-type: os,library + severity: UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL + exit-code: '0' + + - name: Fail on fixable critical or high vulnerabilities + uses: aquasecurity/trivy-action@v0.36.0 + with: + image-ref: markdown-viewer:security-audit + format: table + scanners: vuln + vuln-type: os,library + severity: CRITICAL,HIGH + ignore-unfixed: true + exit-code: '1' + + - name: Upload complete vulnerability scan report + if: always() + uses: actions/upload-artifact@v4 + with: + name: docker-security-report + path: docker-artifacts/trivy-vulnerabilities.json + if-no-files-found: ignore + - name: Build and push Docker image uses: docker/build-push-action@v5 with: context: . + pull: true push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} From e8534ad584e6925b0a4c08709cd0240d4f9b8381 Mon Sep 17 00:00:00 2001 From: Baivab Sarkar <109382325+ThisIs-Developer@users.noreply.github.com> Date: Sun, 15 Nov 2026 17:48:56 +0530 Subject: [PATCH 3/4] fix(ci): create Docker security report directory before Trivy --- .github/workflows/docker-publish.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 30b85082..19390a40 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -61,6 +61,9 @@ jobs: curl -fsSI --max-time 10 http://127.0.0.1:18080/ | grep -qi '^content-security-policy:' ! curl -fsSI --max-time 10 http://127.0.0.1:18080/ | grep -qi 'upgrade-insecure-requests' + - name: Prepare Docker vulnerability report directory + run: mkdir -p docker-artifacts + - name: Scan all known OS and library CVEs (machine-readable artifact) uses: aquasecurity/trivy-action@v0.36.0 with: From 87730b2ac60e0e50ea42852f22186e93854d8ebe Mon Sep 17 00:00:00 2001 From: Baivab Sarkar <109382325+ThisIs-Developer@users.noreply.github.com> Date: Sun, 15 Nov 2026 18:09:40 +0530 Subject: [PATCH 4/4] ci(docker): attest published image provenance and SBOM --- .github/workflows/docker-publish.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 19390a40..377152f2 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -99,6 +99,10 @@ jobs: with: context: . pull: true + # Registry-published images carry provenance and an SBOM attestation. + # Local Docker image-store scans do not inherit registry attestations. + provenance: mode=max + sbom: true push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }}