Add scheduled Docker builds and harden container image
This commit is contained in:
parent
b2d58386c2
commit
6bf9ea48c6
38
.github/workflows/docker-build-daily.yml
vendored
Normal file
38
.github/workflows/docker-build-daily.yml
vendored
Normal 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
|
||||||
38
.github/workflows/docker-build-monthly.yml
vendored
Normal file
38
.github/workflows/docker-build-monthly.yml
vendored
Normal 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
|
||||||
38
.github/workflows/docker-build-weekly.yml
vendored
Normal file
38
.github/workflows/docker-build-weekly.yml
vendored
Normal 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
|
||||||
10
Dockerfile
10
Dockerfile
@ -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
|
||||||
|
|||||||
13
package.json
13
package.json
@ -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"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -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}"
|
||||||
|
|||||||
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user