Skip to content

fix(security): modernize Dockerfile to Node 20, enforce non-root execution, and harden build layers - #44

Open
mertcano wants to merge 1 commit into
circlefin:masterfrom
mertcano:mertcano-patch-1
Open

mertcano wants to merge 1 commit into
circlefin:masterfrom
mertcano:mertcano-patch-1

Conversation

@mertcano

@mertcano mertcano commented Oct 1, 2026

Copy link
Copy Markdown

Summary of Changes

Addresses the High severity security audit finding in repository contract-cli (Cat 21: IaC & container hardening) by upgrading the base runtime, dropping root privileges, and eliminating image layer bloat.


Vulnerability Analysis

  • EOL Node Runtime: The previous node:16 base image is end-of-life and contains known unpatched vulnerabilities.
  • Unbounded Root Execution: Omitting a USER directive meant CLI operations executed as UID 0 (root), increasing the blast radius of any package vulnerability or arbitrary execution vector.
  • Layer Bloat & Stale CVE Surface: Four separate apt-get install commands ran without --no-install-recommends and retained package caches in /var/lib/apt/lists, baking unnecessary packages and outdated dependencies into the image.
  • Build Context Ingestion: Copying the entire context (COPY .) in a single step prior to dependency installation prevented effective layer caching and risked baking untracked local environment secrets into the image layer[cite: 25].

Key Remediations

  1. Node 20 Runtime (node:20-bookworm-slim):
    • Upgraded to active LTS Debian-based slim image, maintaining multi-arch (amd64 and arm64) compatibility[cite: 25].
  2. Layer Hardening & Cache Cleanup:
    • Consolidated system dependencies (wget, openjdk-17-jdk-headless, python3-dev, python3-pip) into a single RUN layer with --no-install-recommends and post-install rm -rf /var/lib/apt/lists/*[cite: 25].
  3. Manifest-First Caching:
    • Isolated manifest copying (COPY package.json yarn.lock* ./) and ran yarn install --frozen-lockfile --ignore-scripts to cache node modules independently of application source edits[cite: 25].
  4. Least-Privilege User:
    • Added USER node at the end of the Dockerfile to guarantee the container process drops root privileges before execution[cite: 25].

Verification

  • Validated Dockerfile instructions, argument syntax, and non-root user permissions[cite: 25].
  • Verified multi-architecture compatibility across amd64 and arm64 build targets[cite: 25].

…ution, and harden build layers

### Summary of Changes
Addresses the **High** severity security audit finding in repository `contract-cli` (Cat 21: IaC & container hardening) by upgrading the base runtime, dropping root privileges, and eliminating image layer bloat.

---

### Vulnerability Analysis
- **EOL Node Runtime:** The previous `node:16` base image is end-of-life and contains known unpatched vulnerabilities.
- **Unbounded Root Execution:** Omitting a `USER` directive meant CLI operations executed as UID 0 (`root`), increasing the blast radius of any package vulnerability or arbitrary execution vector.
- **Layer Bloat & Stale CVE Surface:** Four separate `apt-get install` commands ran without `--no-install-recommends` and retained package caches in `/var/lib/apt/lists`, baking unnecessary packages and outdated dependencies into the image.
- **Build Context Ingestion:** Copying the entire context (`COPY .`) in a single step prior to dependency installation prevented effective layer caching and risked baking untracked local environment secrets into the image layer[cite: 25].

---

### Key Remediations
1. **Node 20 Runtime (`node:20-bookworm-slim`):**
   - Upgraded to active LTS Debian-based slim image, maintaining multi-arch (`amd64` and `arm64`) compatibility[cite: 25].
2. **Layer Hardening & Cache Cleanup:**
   - Consolidated system dependencies (`wget`, `openjdk-17-jdk-headless`, `python3-dev`, `python3-pip`) into a single `RUN` layer with `--no-install-recommends` and post-install `rm -rf /var/lib/apt/lists/*`[cite: 25].
3. **Manifest-First Caching:**
   - Isolated manifest copying (`COPY package.json yarn.lock* ./`) and ran `yarn install --frozen-lockfile --ignore-scripts` to cache node modules independently of application source edits[cite: 25].
4. **Least-Privilege User:**
   - Added `USER node` at the end of the Dockerfile to guarantee the container process drops root privileges before execution[cite: 25].

---

### Verification
- Validated Dockerfile instructions, argument syntax, and non-root user permissions[cite: 25].
- Verified multi-architecture compatibility across `amd64` and `arm64` build targets[cite: 25].
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant