From a51bb11eaf386f7f6a383a189069a0539fae0e2f Mon Sep 17 00:00:00 2001 From: Derek Roberts Date: Thu, 16 Jul 2026 18:16:51 -0700 Subject: [PATCH 1/3] fix(api,chart): prevent stack trace exposure and remove NET_BIND_SERVICE capability --- api/src/services/pub-code-service.js | 8 ++++---- charts/pubcode/values.yaml | 2 -- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/api/src/services/pub-code-service.js b/api/src/services/pub-code-service.js index fcae3e8c..d2f51a57 100644 --- a/api/src/services/pub-code-service.js +++ b/api/src/services/pub-code-service.js @@ -76,7 +76,7 @@ const bulkLoad = async (req, res) => { } } - res.status(500).json(error); + res.status(500).json({ message: "Internal server error" }); } }; const readAll = async (req, res) => { @@ -92,7 +92,7 @@ const readAll = async (req, res) => { logger.error("bulkLoad: ", e); } } - res.status(500).json(error); + res.status(500).json({ message: "Internal server error" }); } }; @@ -103,7 +103,7 @@ const findById = async (req, res) => { res.status(200).json(result); } catch (error) { logger.error("findById: ", error); - res.status(500).json(error); + res.status(500).json({ message: "Internal server error" }); } }; const health = async (req, res) => { @@ -112,7 +112,7 @@ const health = async (req, res) => { res.status(200).json(result); } catch (error) { logger.error("health: ", error); - res.status(500).json(error); + res.status(500).json({ message: "Internal server error" }); } }; const softDeleteRepo = async (req, res) => { diff --git a/charts/pubcode/values.yaml b/charts/pubcode/values.yaml index 7bd43114..5af34c8c 100644 --- a/charts/pubcode/values.yaml +++ b/charts/pubcode/values.yaml @@ -124,8 +124,6 @@ frontend: image: frontend # the exact component name, be it backend, api-1 etc... tag: prod # the tag of the image, it can be latest, 1.0.0 etc..., or the sha256 hash securityContext: - capabilities: - add: [ "NET_BIND_SERVICE" ] readOnlyRootFilesystem: true envFrom: secretRef: From d9aba64b7b54fd0f80348c17e754da7ec5b55e47 Mon Sep 17 00:00:00 2001 From: Derek Roberts Date: Fri, 17 Jul 2026 18:30:08 -0700 Subject: [PATCH 2/3] fix(frontend): strip file capabilities from caddy binary to allow execution without capabilities --- frontend/Dockerfile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 2a925f46..96239e7e 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -11,10 +11,12 @@ FROM caddy:2.11-alpine # Copy static files and config COPY --from=build /app/dist /app/dist COPY Caddyfile /etc/caddy/Caddyfile +RUN caddy fmt /etc/caddy/Caddyfile -# Packages and caddy format -RUN apk add --no-cache ca-certificates && \ - caddy fmt --overwrite /etc/caddy/Caddyfile +# Packages, remove file capabilities, and validate/format config +RUN apk add --no-cache ca-certificates libcap && \ + setcap -r /usr/bin/caddy && \ + apk del libcap # Port, health check and non-root user EXPOSE 3000 3001 From 7dfefd1c0e98c0d99ff3d0247d15d1cd3839fe52 Mon Sep 17 00:00:00 2001 From: Derek Roberts Date: Fri, 17 Jul 2026 18:33:15 -0700 Subject: [PATCH 3/3] Format Caddyfile --- frontend/Caddyfile | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/frontend/Caddyfile b/frontend/Caddyfile index 6db46678..0d3ee649 100644 --- a/frontend/Caddyfile +++ b/frontend/Caddyfile @@ -14,10 +14,10 @@ } encode gzip - handle /env.js { - header { - Content-Type text/javascript - } + handle /env.js { + header { + Content-Type text/javascript + } respond `window.config = {"VITE_SCHEMA_BRANCH":"{$VITE_SCHEMA_BRANCH}", "VITE_POWERBI_URL":"{$VITE_POWERBI_URL}"};` } root * /app/dist @@ -37,9 +37,9 @@ Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate" X-Content-Type-Options "nosniff" Strict-Transport-Security "max-age=31536000" - Content-Security-Policy - https://raw.githubusercontent.com/bcgov/* - "default-src 'self' https://*.gov.bc.ca; + Content-Security-Policy + https://raw.githubusercontent.com/bcgov/* + "default-src 'self' https://*.gov.bc.ca; script-src 'self' https://*.gov.bc.ca ; style-src 'self' https://fonts.googleapis.com https://use.fontawesome.com 'unsafe-inline'; font-src 'self' https://fonts.gstatic.com; @@ -57,7 +57,7 @@ } :3001 { - handle /health { - respond "OK" - } -} \ No newline at end of file + handle /health { + respond "OK" + } +}