Skip to content

Commit 5473ebe

Browse files
authored
Merge pull request #2 from GannaChernyshova/app-update
removed express and app cve remediations for focus on the dhi value more
2 parents 7fa9fcf + b9bfc58 commit 5473ebe

File tree

7 files changed

+61
-102
lines changed

7 files changed

+61
-102
lines changed

.labspace/01-introduction.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
👋 Welcome to the **Docker Hardened Images** lab! This lab outlines the benefits of Docker Hardened Images and walks you through the migration process for the Node application.
44

5+
## First thing to get started, please provide your Docker org name
6+
7+
::variableDefinition[orgname]{prompt="What is your Docker org name?"}
8+
59
## Docker Hardened Images are Secure, Minimal, Production-Ready Images with near-zero CVEs and enterprise-grade SLA for rapid remediation.
610

711
These images follow a distroless philosophy, removing unnecessary components to significantly reduce the attack surface. The result? Smaller images that pull faster, run leaner, and provide a secure-by-default foundation for production workloads:

.labspace/02-mirror-the-image.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
# Getting started
22

3-
## First thing to get started, please provide your Docker org name
4-
5-
::variableDefinition[orgname]{prompt="What is your Docker org name?"}
6-
73
## 1. Mirror a DHI node image repo
84

95
Go to the [Node DHI page](https://hub.docker.com/orgs/$$orgname$$/hardened-images/catalog/dhi/node) and click on the `Mirror to repository` button.

.labspace/03-image-scanning.md

Lines changed: 26 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Exploring the app
44

5-
This demo repository contains a Hello World Node.js application consisting of a basic ExpressJS server and Dockerfile pointing to a Trixie (Debian 13) base image.
5+
This demo repository contains a Hello World Node.js application consisting of a basic JS server and Dockerfile pointing to a Trixie (Debian 13) base image.
66
The app logic is implemented in the :fileLink[app.js]{path="app.js"} file.
77

88

@@ -23,74 +23,40 @@ docker buildx build --provenance=true --sbom=true -t $$orgname$$/demo-node-doi:v
2323
```
2424

2525
2. Now that you have an image let's analyze it.
26-
Use the `docker scout cves` command to list all discovered vulnerabilities:
26+
Use the `docker scout quickview` command to list all discovered vulnerabilities and scout policies alignment:
2727

2828
```bash
29-
docker scout cves $$orgname$$/demo-node-doi:v1
30-
```
31-
32-
After a moment, you will see details about each of the vulnerabilities discovered in the image with a similar summary.
33-
34-
```plaintext no-copy-button
35-
34 vulnerabilities found in 17 packages
36-
CRITICAL 0
37-
HIGH 6
38-
MEDIUM 2
39-
LOW 26
40-
```
41-
42-
A couple of things to note about this:
43-
44-
- If you scroll up or search the `pkg:npm/[email protected]` - this part of the report is related to the NPM package named `express`, which has version 4.17.1. You should see that the greatest fix version is `4.20.0`
45-
- Another source of HIGH CVEs is a `path-to-regexp 0.1.7`. The `express` package uses it internally and the `path-to-regexp` library is updated to a fixed version in express version `4.21.2`.
46-
- Aslo you may see another HIGH CVE `pkg:npm/[email protected]`
47-
48-
3. A common next step for developers is to clean up the package.json by updating dependencies to address known vulnerabilities.
49-
50-
You could upgrade each dependency manually, but to simplify this process during the lab, let's use the following command, which automatically applies available fixes (and may update some packages to newer major versions):
51-
52-
```bash
53-
npm audit fix --force
54-
```
55-
56-
4. Build your image again by running the following command:
57-
```bash
58-
docker buildx build --provenance=true --sbom=true -t $$orgname$$/demo-node-doi:v2 .
59-
```
60-
61-
5. And run one more analysis on the image.
62-
You can now analyze the image with the `docker scout quickview` command:
63-
64-
```bash
65-
docker scout quickview $$orgname$$/demo-node-doi:v2
29+
docker scout quickview $$orgname$$/demo-node-doi:v1
6630
```
6731
You will see similar output:
6832
```plaintext no-copy-button
69-
Target │ $$orgname$$/demo-node-doi:v2 │ 0C 1H 1M 22L
70-
digest │ 48bd36fe1f0b │
71-
Base image │ node:24.9.0-trixie-slim │ 0C 1H 1M 22L
72-
73-
Policy status FAILED (6/9 policies met)
74-
75-
Status │ Policy │ Results
76-
─────────┼────────────────────────────────────────────────┼──────────────────────────────
77-
✓ │ AGPL v3 licenses found │ 0 packages
78-
! │ No default non-root user found │
79-
✓ │ No AGPL v3 licenses │ 0 packages
80-
✓ │ No embedded secrets │ 0 deviations
81-
✓ │ No embedded secrets (Rego) │ 0 deviations
82-
! │ Fixable critical or high vulnerabilities found │ 0C 1H 0M 0L
83-
✓ │ No high-profile vulnerabilities │ 0C 0H 0M 0L
84-
! │ Unapproved base images found │ 1 deviation
85-
✓ │ Supply chain attestations │ 0 deviations
33+
i Base image was auto-detected. To get more accurate results, build images with max-mode provenance attestations.
34+
Review docs.docker.com ↗ for more information.
35+
36+
Target │ demonstrationorg/demo-node-doi:v1 │ 0C 2H 1M 18L
37+
digest │ 66cb8da420d8 │
38+
Base image │ node:24-trixie-slim │ 0C 2H 1M 18L
39+
40+
Policy status FAILED (5/10 policies met, 1 missing data)
41+
42+
Status │ Policy │ Results
43+
─────────┼──────────────────────────────────────────────────────────────────┼──────────────────────────────
44+
✓ │ AGPL v3 licenses found │ 0 packages
45+
! │ No default non-root user found │
46+
✓ │ No AGPL v3 licenses │ 0 packages
47+
✓ │ No embedded secrets │ 0 deviations
48+
✓ │ No embedded secrets (Rego) │ 0 deviations
49+
! │ Fixable critical or high vulnerabilities found │ 0C 2H 0M 0L
50+
✓ │ No high-profile vulnerabilities │ 0C 0H 0M 0L
51+
! │ No unapproved base images │ No data
52+
✓ │ Missing supply chain attestation(s) │ 2 deviations
8653
8754
```
88-
89-
Hooray! No more critical or high CVEs on the application level!
90-
But there are still a few on the base image level. And the critical policies have failed:
55+
As you can see, there are no CVEs at the application level, but the base image contains 2 high, 1 medium, and 18 low severity CVEs, so it is recommended to be updated. Additionally, the critical policies have failed:
9156

9257
1. No default non-root user found
9358
2. Fixable critical or high vulnerabilities found
9459
3. Unapproved base images found
95-
This is where DHI comes into play.
60+
61+
This is where DHI comes into play.
9662

.labspace/04-switch-to-dhi.md

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -51,31 +51,32 @@ Hooray! There are zero CVEs and policy violations now!
5151

5252
Docker Scout offers a helpful command `docker scout compare` that allows you to analyze and compare two images. We’ll use it to evaluate the difference in size and package footprint between `node:24.9.0-trixie-slim` and `dhi-node:24.9.0-debian13` based images.
5353
```bash
54-
docker scout compare local://$$orgname$$/demo-node-doi:v2 --to local://$$orgname$$/demo-node-dhi:v1
54+
docker scout compare local://$$orgname$$/demo-node-dhi:v1 --to local://$$orgname$$/demo-node-doi:v1
5555
```
5656
You will see a similar summary in the output:
5757
```plaintext no-copy-button
5858
## Overview
5959
6060
│ Analyzed Image │ Comparison Image
6161
────────────────────┼─────────────────────────────────────────────┼──────────────────────────────────────────────
62-
Target │ local://$$orgname$$/demo-node-doi:v2 │ local://$$orgname$$/demo-node-dhi:v1
63-
digest │ 75eb23bc5d85e7a47068ccfa
64-
tag │ v2 │ v1
62+
Target │ local://demonstrationorg/demo-node-dhi:v1 │ local://demonstrationorg/demo-node-doi:v1
63+
digest │ e5b9ec7a980c66cb8da420d8
64+
tag │ v1 │ v1
6565
platform │ linux/arm64 │ linux/arm64
66-
vulnerabilities │ 0C 6H 2M 26L │ 0C 0H 0M 8L
67-
+6 +2 +18
68-
size │ 100 MB (+41 MB) │ 59 MB
69-
packages │ 901 (+248) │ 653
66+
vulnerabilities │ 0C 0H 0M 8L │ 0C 2H 1M 18L
67+
-2 -1 -10
68+
size │ 59 MB (-41 MB) │ 100 MB
69+
packages │ 648 (-248) │ 896
7070
│ │
71-
Base image │ node:24.9.0-trixie-slim │ $$orgname$$/dhi-node:24.9.0-debian13
71+
Base image │ demonstrationorg/dhi-node-smontri:24 │ node:24-trixie-slim
7272
tags │ also known as │ also known as
73-
│ • current-trixie-slim │
74-
│ • trixie-slim │
75-
vulnerabilities │ 0C 1H 1M 22L │ 0C 0H 0M 0L
73+
│ │ • current-trixie-slim
74+
│ │ • trixie-slim
75+
vulnerabilities │ 0C 0H 0M 0L │ 0C 2H 1M 18L
76+
7677
```
7778

78-
As you can see, the original `node:24.9.0-trixie-slim` based image is 41 MB larger, has 248 more packages, and includes high, medium, and low CVEs. The `dhi-node:24.9.0-debian13` based image is 40% smaller and has near-zero CVEs.
79+
As you can see, the `dhi-node:24.9.0-debian13`based image is **41 MB (around 40%) smaller**, contains **248 fewer packages**, and has nearly **zero CVEs** compared to the original `node:24.9.0-trixie-slim`based image.
7980

8081
**Validate that the app works as expected**
8182

app.js

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
1-
const express = require('express');
1+
const http = require('http');
22

3-
const app = express();
43
const port = 3000;
54

6-
app.get('/', (req, res) => {
7-
res.send('Hello World!');
5+
const server = http.createServer((req, res) => {
6+
if (req.url === '/' && req.method === 'GET') {
7+
res.writeHead(200, { 'Content-Type': 'text/plain' });
8+
res.end('Hello World!');
9+
} else {
10+
res.writeHead(404);
11+
res.end('Not Found');
12+
}
813
});
914

10-
app.listen(port, () => {
11-
console.log(`Example app listening on port ${port}`);
15+
server.listen(port, () => {
16+
console.log(`Server listening on port ${port}`);
1217
});

package.json

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,22 @@
11
{
22
"name": "@docker/scout-demo-service",
33
"version": "0.1.0",
4-
"description": "A boilerplate for Node.js web applications",
4+
"description": "A simple Node.js service with Jest and Testcontainers",
55
"repository": {
66
"type": "git",
7-
"url": "https://github.com/docker/scout-demo-servixe.git"
7+
"url": "https://github.com/docker/scout-demo-service.git"
88
},
9-
"license": "Apache-2",
9+
"license": "Apache-2.0",
1010
"scripts": {
1111
"start": "node app.js",
12-
"test": "jest --testTimeout=60000",
13-
"lint": "eslint \"**/*.js\""
14-
},
15-
"dependencies": {
16-
"express": "4.17.1"
12+
"test": "jest --testTimeout=60000"
1713
},
1814
"devDependencies": {
19-
"axios": "^1.6.0",
20-
"eslint": "^7.17.0",
21-
"eslint-config-airbnb-base": "^14.2.1",
22-
"eslint-plugin-chai-friendly": "^0.6.0",
23-
"eslint-plugin-import": "^2.22.1",
2415
"jest": "^29.7.0",
2516
"testcontainers": "^10.13.2"
2617
},
27-
"engines": {
28-
"node": ">=10.23.1",
29-
"npm": ">=6.14.10"
30-
},
3118
"jest": {
3219
"testEnvironment": "node",
3320
"testTimeout": 60000
3421
}
35-
}
22+
}

test/app.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ describe('App Integration Tests', () => {
1313

1414
container = await builtContainer
1515
.withExposedPorts(3000)
16-
.withWaitStrategy(Wait.forLogMessage(/Example app listening on port \d+/))
16+
.withWaitStrategy(Wait.forLogMessage(/Server listening on port \d+/))
1717
.start();
1818

1919
// Get the mapped port

0 commit comments

Comments
 (0)