From 59fd5285351c14f6e9cde073bd983de073fa3a75 Mon Sep 17 00:00:00 2001 From: Anso Date: Sun, 29 Mar 2026 22:31:19 -0400 Subject: [PATCH] fix: remediate Dependabot and Docker Scout security vulnerabilities (#265) - Upgrade Docker base image from node:20-alpine to node:22-alpine (Node 22.22.2, Alpine 3.23.3) to resolve 31 CVEs flagged by Docker Scout - Add apk upgrade to runtime stage for latest Alpine security patches - Force dompurify to 3.3.3 via npm overrides to fix two XSS advisories (transitive dep of monaco-editor pinned at 3.2.7) --- CHANGELOG.md | 6 ++++++ Dockerfile | 14 ++++++++------ frontend/package-lock.json | 6 +++--- frontend/package.json | 3 +++ 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee5d659f..e64d1520 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Security + +* **docker:** upgrade base image from `node:20-alpine` to `node:22-alpine` (Node 22.22.2 on Alpine 3.23.3) to remediate 31 CVEs (1 Critical, multiple High/Medium/Low) flagged by Docker Scout against the previous `node:20-alpine` base. +* **docker:** add `apk upgrade --no-cache` to runtime stage to ensure all Alpine system packages are at their latest patched versions at build time. +* **deps:** force `dompurify` to 3.3.3 via npm overrides to resolve two Dependabot advisories (Mutation-XSS via Re-Contextualization and Cross-site Scripting) in the transitive dependency pulled by `monaco-editor`. + ### Fixed * **stacks:** resolve permission denied error when deleting stacks with root-owned files. Sencho now falls back to Docker-based cleanup when the normal deletion fails due to EACCES/EPERM, handling directories created by Docker Compose as root without requiring elevated privileges. diff --git a/Dockerfile b/Dockerfile index 1ffd8f8d..9512236f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ FROM --platform=$BUILDPLATFORM tonistiigi/xx AS xx # Stage 1: Build Frontend # Runs on the BUILD platform (amd64) - frontend has no native modules so the # compiled output (JS/CSS/HTML) is entirely platform-agnostic. -FROM --platform=$BUILDPLATFORM node:20-alpine AS frontend-builder +FROM --platform=$BUILDPLATFORM node:22-alpine AS frontend-builder WORKDIR /app/frontend @@ -21,7 +21,7 @@ RUN npm run build # Stage 2: Compile TypeScript # Runs on the BUILD platform (amd64) - tsc output is platform-agnostic JS. -FROM --platform=$BUILDPLATFORM node:20-alpine AS backend-builder +FROM --platform=$BUILDPLATFORM node:22-alpine AS backend-builder WORKDIR /app/backend @@ -41,7 +41,7 @@ RUN npm run build # tonistiigi/xx + clang as the cross-compiler. # This avoids the Node.js v20 SIGILL crash that occurs when npm runs # under QEMU because QEMU lacks ARMv8.1 LSE atomic instruction support. -FROM --platform=$BUILDPLATFORM node:20-alpine AS prod-deps +FROM --platform=$BUILDPLATFORM node:22-alpine AS prod-deps # Copy xx cross-compilation tools into this stage COPY --from=xx / / @@ -89,10 +89,12 @@ RUN if [ "$TARGETARCH" = "$BUILDARCH" ]; then \ # Stage 4: Production runtime # Runs on the TARGET platform - no compilation happens here. -FROM node:20-alpine +FROM node:22-alpine -# Install Docker CLI, Docker Compose CLI, and Bash for Host Console -RUN apk add --no-cache docker-cli docker-cli-compose bash su-exec +# Upgrade all Alpine system packages to pick up security patches, then install +# Docker CLI, Docker Compose CLI, and Bash for Host Console +RUN apk upgrade --no-cache && \ + apk add --no-cache docker-cli docker-cli-compose bash su-exec WORKDIR /app diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 53e9146c..2d79b87c 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -3861,9 +3861,9 @@ "license": "MIT" }, "node_modules/dompurify": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.7.tgz", - "integrity": "sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.3.tgz", + "integrity": "sha512-Oj6pzI2+RqBfFG+qOaOLbFXLQ90ARpcGG6UePL82bJLtdsa6CYJD7nmiU8MW9nQNOtCHV3lZ/Bzq1X0QYbBZCA==", "license": "(MPL-2.0 OR Apache-2.0)", "optionalDependencies": { "@types/trusted-types": "^2.0.7" diff --git a/frontend/package.json b/frontend/package.json index ee855b26..310d1235 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -53,6 +53,9 @@ "xterm-addon-search": "^0.13.0", "xterm-addon-serialize": "^0.11.0" }, + "overrides": { + "dompurify": "^3.3.3" + }, "devDependencies": { "@eslint/js": "^10.0.1", "@tailwindcss/vite": "^4.2.2",