Merge pull request #5 from mkilijanek/codex/review-branches-for-security-issues

Add scheduled Docker builds and harden container image
This commit is contained in:
Kili 2025-12-19 20:12:09 +01:00 committed by GitHub
commit a6d13e5a36
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 147 additions and 23 deletions

View File

@ -0,0 +1,38 @@
name: Daily Docker Build
on:
workflow_dispatch:
schedule:
- cron: "0 2 * * *"
jobs:
build-and-scan:
name: Build and scan Docker image (daily)
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build image from fresh base layers
run: |
docker buildx build \
--pull \
--load \
--tag cyberchef:${{ github.sha }} \
-f Dockerfile .
- name: Scan image for High/Critical issues (fails on detection)
uses: aquasecurity/trivy-action@0.24.0
with:
image-ref: cyberchef:${{ github.sha }}
format: table
vuln-type: "os,library"
severity: "CRITICAL,HIGH"
exit-code: "1"
ignore-unfixed: false

View File

@ -0,0 +1,38 @@
name: Monthly Docker Build
on:
workflow_dispatch:
schedule:
- cron: "0 4 1 * *"
jobs:
build-and-scan:
name: Build and scan Docker image (monthly)
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build image from fresh base layers
run: |
docker buildx build \
--pull \
--load \
--tag cyberchef:${{ github.sha }} \
-f Dockerfile .
- name: Scan image for High/Critical issues (fails on detection)
uses: aquasecurity/trivy-action@0.24.0
with:
image-ref: cyberchef:${{ github.sha }}
format: table
vuln-type: "os,library"
severity: "CRITICAL,HIGH"
exit-code: "1"
ignore-unfixed: false

View File

@ -0,0 +1,38 @@
name: Weekly Docker Build
on:
workflow_dispatch:
schedule:
- cron: "0 3 * * 1"
jobs:
build-and-scan:
name: Build and scan Docker image (weekly)
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build image from fresh base layers
run: |
docker buildx build \
--pull \
--load \
--tag cyberchef:${{ github.sha }} \
-f Dockerfile .
- name: Scan image for High/Critical issues (fails on detection)
uses: aquasecurity/trivy-action@0.24.0
with:
image-ref: cyberchef:${{ github.sha }}
format: table
vuln-type: "os,library"
severity: "CRITICAL,HIGH"
exit-code: "1"
ignore-unfixed: false

View File

@ -4,7 +4,7 @@
# Modifier --platform=$BUILDPLATFORM limits the platform to "BUILDPLATFORM" during buildx multi-platform builds # Modifier --platform=$BUILDPLATFORM limits the platform to "BUILDPLATFORM" during buildx multi-platform builds
# This is because npm "chromedriver" package is not compatiable with all platforms # This is because npm "chromedriver" package is not compatiable with all platforms
# For more info see: https://docs.docker.com/build/building/multi-platform/#cross-compilation # For more info see: https://docs.docker.com/build/building/multi-platform/#cross-compilation
FROM --platform=$BUILDPLATFORM node:18-alpine AS builder FROM --platform=$BUILDPLATFORM node:22-alpine AS builder
WORKDIR /app WORKDIR /app
@ -13,7 +13,7 @@ COPY package-lock.json .
# Install dependencies # Install dependencies
# --ignore-scripts prevents postinstall script (which runs grunt) as it depends on files other than package.json # --ignore-scripts prevents postinstall script (which runs grunt) as it depends on files other than package.json
RUN npm ci --ignore-scripts RUN npm ci --ignore-scripts --no-audit --no-fund
# Copy files needed for postinstall and build # Copy files needed for postinstall and build
COPY . . COPY . .
@ -30,6 +30,8 @@ RUN npm run build
# We are using Github Actions: redhat-actions/buildah-build@v2 which needs manual selection of arch in base image # We are using Github Actions: redhat-actions/buildah-build@v2 which needs manual selection of arch in base image
# Remove TARGETARCH if docker buildx is supported in the CI release as --platform=$TARGETPLATFORM will be automatically set # Remove TARGETARCH if docker buildx is supported in the CI release as --platform=$TARGETPLATFORM will be automatically set
ARG TARGETPLATFORM ARG TARGETPLATFORM
FROM --platform=${TARGETPLATFORM} nginx:stable-alpine AS cyberchef FROM --platform=${TARGETPLATFORM} nginx:1.27-alpine AS cyberchef
COPY --from=builder /app/build/prod /usr/share/nginx/html/ COPY --from=builder --chown=nginx:nginx /app/build/prod /usr/share/nginx/html/
USER nginx

View File

@ -44,7 +44,8 @@
"@babel/plugin-syntax-import-assertions": "^7.24.7", "@babel/plugin-syntax-import-assertions": "^7.24.7",
"@babel/plugin-transform-runtime": "^7.24.7", "@babel/plugin-transform-runtime": "^7.24.7",
"@babel/preset-env": "^7.24.7", "@babel/preset-env": "^7.24.7",
"@babel/runtime": "^7.24.7", "@babel/runtime": "^7.26.10",
"@babel/helpers": "^7.26.10",
"@codemirror/commands": "^6.6.0", "@codemirror/commands": "^6.6.0",
"@codemirror/language": "^6.10.2", "@codemirror/language": "^6.10.2",
"@codemirror/search": "^6.5.6", "@codemirror/search": "^6.5.6",
@ -91,7 +92,7 @@
"terser": "^5.31.1", "terser": "^5.31.1",
"webpack": "^5.91.0", "webpack": "^5.91.0",
"webpack-bundle-analyzer": "^4.10.2", "webpack-bundle-analyzer": "^4.10.2",
"webpack-dev-server": "5.0.4", "webpack-dev-server": "^5.11.0",
"webpack-node-externals": "^3.0.0", "webpack-node-externals": "^3.0.0",
"worker-loader": "^3.0.8" "worker-loader": "^3.0.8"
}, },
@ -100,11 +101,11 @@
"@babel/polyfill": "^7.12.1", "@babel/polyfill": "^7.12.1",
"@blu3r4y/lzma": "^2.3.3", "@blu3r4y/lzma": "^2.3.3",
"@wavesenterprise/crypto-gost-js": "^2.1.0-RC1", "@wavesenterprise/crypto-gost-js": "^2.1.0-RC1",
"@xmldom/xmldom": "^0.8.10", "@xmldom/xmldom": "^0.9.3",
"argon2-browser": "^1.18.0", "argon2-browser": "^1.18.0",
"arrive": "^2.4.1", "arrive": "^2.4.1",
"avsc": "^5.7.7", "avsc": "^5.7.7",
"bcryptjs": "^2.4.3", "bcryptjs": "^3.0.3",
"bignumber.js": "^9.1.2", "bignumber.js": "^9.1.2",
"blakejs": "^1.2.1", "blakejs": "^1.2.1",
"bootstrap": "4.6.2", "bootstrap": "4.6.2",
@ -144,7 +145,7 @@
"json5": "^2.2.3", "json5": "^2.2.3",
"jsonata": "^2.0.3", "jsonata": "^2.0.3",
"jsonpath-plus": "^9.0.0", "jsonpath-plus": "^9.0.0",
"jsonwebtoken": "8.5.1", "jsonwebtoken": "^9.0.2",
"jsqr": "^1.4.0", "jsqr": "^1.4.0",
"jsrsasign": "^11.1.0", "jsrsasign": "^11.1.0",
"kbpgp": "2.1.15", "kbpgp": "2.1.15",
@ -185,7 +186,7 @@
"utf8": "^3.0.0", "utf8": "^3.0.0",
"uuid": "^11.1.0", "uuid": "^11.1.0",
"vkbeautify": "^0.99.3", "vkbeautify": "^0.99.3",
"xpath": "0.0.34", "xpath": "^0.0.35",
"xregexp": "^5.1.1", "xregexp": "^5.1.1",
"zlibjs": "^0.3.1" "zlibjs": "^0.3.1"
}, },

View File

@ -42,7 +42,7 @@ npm install --save-dev @babel/helpers@^7.26.10 || echo -e "${RED}Failed to updat
# Update webpack-dev-server (Source code theft vulnerability) # Update webpack-dev-server (Source code theft vulnerability)
echo "3. Updating webpack-dev-server (GHSA-9jgg-88mc-972h)..." echo "3. Updating webpack-dev-server (GHSA-9jgg-88mc-972h)..."
npm install --save-dev webpack-dev-server@^5.2.2 || echo -e "${RED}Failed to update webpack-dev-server${NC}" npm install --save-dev webpack-dev-server@^5.11.0 || echo -e "${RED}Failed to update webpack-dev-server${NC}"
# Update tmp (Symlink vulnerability) # Update tmp (Symlink vulnerability)
echo "4. Updating tmp (GHSA-52f5-9888-hmc6)..." echo "4. Updating tmp (GHSA-52f5-9888-hmc6)..."
@ -52,6 +52,18 @@ npm install --save-dev tmp@^0.2.5 || echo -e "${RED}Failed to update tmp${NC}"
echo "5. Updating bcryptjs (recommended)..." echo "5. Updating bcryptjs (recommended)..."
npm install bcryptjs@^3.0.3 || echo -e "${RED}Failed to update bcryptjs${NC}" npm install bcryptjs@^3.0.3 || echo -e "${RED}Failed to update bcryptjs${NC}"
# Update @xmldom/xmldom (multiple advisories)
echo "6. Updating @xmldom/xmldom..."
npm install @xmldom/xmldom@^0.9.3 || echo -e "${RED}Failed to update @xmldom/xmldom${NC}"
# Update jsonwebtoken (CVE-2022-23529 and other fixes)
echo "7. Updating jsonwebtoken..."
npm install jsonwebtoken@^9.0.2 || echo -e "${RED}Failed to update jsonwebtoken${NC}"
# Update xpath (ReDoS fixes)
echo "8. Updating xpath..."
npm install xpath@^0.0.35 || echo -e "${RED}Failed to update xpath${NC}"
echo "" echo ""
echo -e "${YELLOW}🔍 Running npm audit fix...${NC}" echo -e "${YELLOW}🔍 Running npm audit fix...${NC}"
npm audit fix || echo -e "${YELLOW}⚠ npm audit fix completed with warnings${NC}" npm audit fix || echo -e "${YELLOW}⚠ npm audit fix completed with warnings${NC}"

View File

@ -35,6 +35,7 @@ import {
searchKeymap, searchKeymap,
highlightSelectionMatches highlightSelectionMatches
} from "@codemirror/search"; } from "@codemirror/search";
import DOMPurify from "dompurify";
import {statusBar} from "../utils/statusBar.mjs"; import {statusBar} from "../utils/statusBar.mjs";
import {htmlPlugin} from "../utils/htmlWidget.mjs"; import {htmlPlugin} from "../utils/htmlWidget.mjs";
@ -350,7 +351,12 @@ class OutputWaiter {
* @param {string} html * @param {string} html
*/ */
async setHTMLOutput(html) { async setHTMLOutput(html) {
this.htmlOutput.html = html; const sanitizedHtml = DOMPurify.sanitize(html, {
USE_PROFILES: {html: true},
FORBID_TAGS: ["script"],
RETURN_TRUSTED_TYPE: false
});
this.htmlOutput.html = sanitizedHtml;
this.htmlOutput.changed = true; this.htmlOutput.changed = true;
// This clears the text output, but also fires a View update which // This clears the text output, but also fires a View update which
// triggers the htmlWidget to render the HTML. We set the force flag // triggers the htmlWidget to render the HTML. We set the force flag
@ -364,17 +370,6 @@ class OutputWaiter {
// Add class to #output-text to change display settings // Add class to #output-text to change display settings
this.outputTextEl.classList.add("html-output"); this.outputTextEl.classList.add("html-output");
// Execute script sections
const outputHTML = document.getElementById("output-html");
const scriptElements = outputHTML ? outputHTML.querySelectorAll("script") : [];
for (let i = 0; i < scriptElements.length; i++) {
try {
eval(scriptElements[i].innerHTML); // eslint-disable-line no-eval
} catch (err) {
log.error(err);
}
}
} }
/** /**