Files
Charon/docs/reports/qa_report.md

135 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# QA Audit Report — Dockerfile npm CVE Remediation
**Date:** 2026-03-16
**Scope:** `Dockerfile``frontend-builder` stage npm upgrade to address 6 HIGH CVEs in `node:24.14.0-alpine`
**Reviewer:** QA Security Agent
---
## Overall Verdict: APPROVED
All structural, linting, and security gates pass. The change is correctly scoped to the build-only `frontend-builder` stage and introduces no new attack surface in the final runtime image.
---
## Changes Under Review
| Element | Location | Description |
|---|---|---|
| `ARG NPM_VERSION=11.11.1` | Line 30 (global ARG block) | Pinned npm version with Renovate comment |
| `ARG NPM_VERSION` | Line 105 (frontend-builder) | Bare re-declaration to inherit global ARG into stage |
| `# hadolint ignore=DL3017` | Line 106 | Lint suppression for intentional `apk upgrade` |
| `RUN apk upgrade --no-cache && ...` | Lines 107109 | Three-command RUN: OS patch + npm upgrade + cache clear |
| `RUN npm ci` | Line 111 | Unchanged dependency install follows the new RUN block |
---
## Gate Summary
| # | Gate | Result | Details |
|---|---|---|---|
| 1 | Global `ARG NPM_VERSION` present with Renovate comment | **PASS** | Line 30; `# renovate: datasource=npm depName=npm` at line 29 |
| 2 | `ARG NPM_VERSION` bare re-declaration inside stage | **PASS** | Line 105 |
| 3 | `# hadolint ignore=DL3017` on own line before RUN block | **PASS** | Line 106 |
| 4 | RUN block — three correct commands | **PASS** | Lines 107109: `apk upgrade --no-cache`, `npm install -g npm@${NPM_VERSION} --no-fund --no-audit`, `npm cache clean --force` |
| 5 | `RUN npm ci` still present and follows new block | **PASS** | Line 111 |
| 6 | FROM line unchanged | **PASS** | `node:24.14.0-alpine@sha256:7fddd9ddeae8196abf4a3ef2de34e11f7b1a722119f91f28ddf1e99dcafdf114` |
| 7 | `${NPM_VERSION}` used (no hard-coded version) | **PASS** | Confirmed variable reference in install command |
| 8 | Trivy config scan (HIGH/CRITICAL) | **PASS** | 0 misconfigurations |
| 9 | Hadolint (new code area) | **PASS** | No errors or warnings; only pre-existing `info`-level DL3059 at unrelated lines |
| 10 | Runtime image isolation | **PASS** | Only `/app/frontend/dist` artifacts copied into final image via line 535 |
| 11 | `--no-audit` acceptability | **PASS** | Applies only to the single-package global npm upgrade; `npm ci` is unaffected |
| 12 | `npm cache clean --force` safety | **PASS** | Safe cache clear between npm tool upgrade and dependency install |
---
## 1. Dockerfile Structural Verification
### Global ARG block (lines 2540)
```
29: # renovate: datasource=npm depName=npm
30: ARG NPM_VERSION=11.11.1
```
Both the Renovate comment and the pinned ARG are present in the correct order. Renovate will track `npm` releases on `datasource=npm` and propose version bumps automatically.
### frontend-builder stage (lines 93115)
```
93: FROM --platform=$BUILDPLATFORM node:24.14.0-alpine@sha256:... AS frontend-builder
...
105: ARG NPM_VERSION
106: # hadolint ignore=DL3017
107: RUN apk upgrade --no-cache && \
108: npm install -g npm@${NPM_VERSION} --no-fund --no-audit && \
109: npm cache clean --force
...
111: RUN npm ci
```
All structural requirements confirmed: bare re-declaration, lint suppression on dedicated line, three-command RUN, and unmodified `npm ci`.
---
## 2. Security Tool Results
### Trivy config scan
**Command:** `docker run aquasec/trivy config Dockerfile --severity HIGH,CRITICAL`
```
Report Summary
┌────────────┬────────────┬───────────────────┐
│ Target │ Type │ Misconfigurations │
├────────────┼────────────┼───────────────────┤
│ Dockerfile │ dockerfile │ 0 │
└────────────┴────────────┴───────────────────┘
```
No HIGH or CRITICAL misconfigurations detected.
### Hadolint
**Command:** `docker run hadolint/hadolint < Dockerfile`
Findings affecting the new code: **none**.
Pre-existing `info`-level findings (unrelated to this change):
| Line | Rule | Message |
|---|---|---|
| 78, 81, 137, 335, 338 | DL3059 info | Multiple consecutive RUN — pre-existing pattern |
| 492 | SC2012 info | Use `find` instead of `ls` — unrelated |
No errors or warnings in the `frontend-builder` section.
---
## 3. Logical Security Review
### Attack surface — build-only stage
The `frontend-builder` stage is strictly a build artifact producer. The final runtime image receives only compiled frontend assets via a single targeted `COPY`:
```
COPY --from=frontend-builder /app/frontend/dist /app/frontend/dist
```
The Alpine OS packages upgraded by `apk upgrade --no-cache`, the globally installed npm binary, and all `node_modules` are confined to the builder layer and never reach the runtime image. The CVE remediation has zero footprint in the deployed container.
### `--no-audit` flag
`--no-audit` suppresses npm audit output during `npm install -g npm@${NPM_VERSION}`. This applies only to the single-package global npm tool upgrade, not to the project dependency installation. `npm ci` on line 111 installs project dependencies from `package-lock.json` and is unaffected by this flag. Suppressing audit during a build-time tool upgrade is the standard pattern for avoiding advisory database noise that cannot be acted on during the image build.
### `npm cache clean --force`
Clears the npm package cache between the global npm upgrade and the `npm ci` run. This is safe: it ensures the freshly installed npm binary is used without stale cache entries left by the older npm version bundled in the base image. The `--force` flag suppresses npm's deprecation warning about manual cache cleaning; it does not alter the clean operation itself.
---
## Blocking Issues
None.