Lab — Week 4: Container Security II — Scanning, Supply Chain, and Monitoring
Due: 31 July 2026
Submission: GitLab repo secdevops-s26-<CECS>
- Overview
- Prerequisites
- Part 1: Image Scanning and Supply Chain Security
- Part 2: Container Networking, Secrets Integration, and Wazuh Agent
- Submission
Overview
Look inside the containers — scanning for known CVEs in OS packages and dependencies — and bring the Wazuh agent online so everything from here on is observed.
- Part 1 — Image Scanning and Supply Chain Security scans your hardened images for known CVEs, makes evidence-based remediation decisions, generates an SBOM, and produces a CI-ready scanning script.
- Part 2 — Container Networking, Secrets Integration, and Wazuh Agent delivers secrets to containers without exposing them, verifies network segmentation, and registers the Wazuh agent so everything from here on is observed by the SIEM.
Prerequisites
- Week 3 Part 2 complete — hardened images built and stack running
- Week 2 Part 2 complete — OpenBao running and unsealed on ubuntu-server (for Part 2)
- Wazuh manager running on 10.10.10.30 (for Part 2)
Part 1: Image Scanning and Supply Chain Security
Every container image inherits vulnerabilities from every layer below it. This part scans your hardened images for known CVEs, makes evidence-based remediation decisions, generates an SBOM, and produces a scanning script suitable for use in a CI pipeline.
Initial Scan
- Scan each image for HIGH and CRITICAL vulnerabilities:
trivy image --severity HIGH,CRITICAL dvwa:hardened trivy image --severity HIGH,CRITICAL nginx-proxy:hardened trivy image --severity HIGH,CRITICAL mariadb:11 - Save the reports in JSON format:
trivy image --format json --output lab07/trivy-dvwa-before.json dvwa:hardened trivy image --format json --output lab07/trivy-nginx-before.json nginx-proxy:hardened
Triage and Remediation
-
For every HIGH and CRITICAL finding across all images, complete a triage entry in
lab07/triage.mdusing this format:CVE Severity Package Image Classification Rationale Action CVE-XXXX-XXXX CRITICAL libssl3 dvwa True Positive — fix Remotely exploitable in network service Rebuild with updated base Classification must be one of:
- True Positive — fix: exploitable in your environment; rebuild
- True Positive — accept: exploitable but mitigated elsewhere; document rationale
- False Positive: scanner error or not applicable; document reasoning
-
For every True Positive — fix finding: update the relevant Dockerfile to use a newer base image or explicitly upgrade the affected package, rebuild the image, and re-scan to confirm the CVE no longer appears.
-
Save post-remediation scans:
trivy image --format json --output lab07/trivy-dvwa-after.json dvwa:hardened trivy image --format json --output lab07/trivy-nginx-after.json nginx-proxy:hardened
SBOM Generation
- Generate a CycloneDX SBOM for the hardened DVWA image:
trivy sbom --format cyclonedx --output lab07/sbom-dvwa.json dvwa:hardened - Answer in
lab07/lab07.md: if CVE-2021-44228 (Log4Shell) were disclosed today, how would you use this SBOM to determine whether your DVWA image is affected? What command would you run?
CI Gate Script
- Write
scripts/scan-images.shthat:- Scans
dvwa:hardenedandnginx-proxy:hardened - Exits non-zero if any CRITICAL CVE is found in either image
- Prints a summary line for each image (e.g.,
dvwa:hardened — 0 CRITICAL, 2 HIGH)
- Scans
- Run the script and confirm it exits 0 with your remediated images.
Deliverables
Create lab07/ in your repo containing:
trivy-dvwa-before.jsonandtrivy-nginx-before.json— pre-remediation scanstriage.md— triage table for all HIGH/CRITICAL findings- Updated Dockerfiles — showing the remediation changes
trivy-dvwa-after.jsonandtrivy-nginx-after.json— post-remediation scanssbom-dvwa.json— CycloneDX SBOM for DVWAscripts/scan-images.sh— CI gate script with passing outputlab07/lab07.md— SBOM Log4Shell answer and a brief reflection on CVE count before vs. after
Part 2: Container Networking, Secrets Integration, and Wazuh Agent
This part connects three threads: secrets from OpenBao reach containers without appearing in environment variables, network segmentation is verified by attempting forbidden connections, and the Wazuh agent is registered so that everything you do from this point forward is observed by the SIEM.
Part 1 and Week 2 Part 2 must be complete — hardened stack running and OpenBao running and unsealed; the Wazuh manager must be running on 10.10.10.30.
Secrets Integration
-
Update
docker-compose.ymlto pass the DVWA database password from OpenBao rather than hardcoding it. Use Docker Compose secrets or an OpenBao Agent sidecar — your choice. Document your approach.Option A — Docker Compose secrets:
secrets: db_password: file: ./secrets/db_password.txt # populated from OpenBao at deploy time services: dvwa: secrets: [db_password] # reads /run/secrets/db_password at runtimeOption B — OpenBao Agent sidecar: configure an
openbao-agentcontainer that writes the secret to a shared volume mounted into thedvwacontainer. -
Verify the password is not visible in
docker inspect:docker inspect $(docker compose ps -q dvwa) \ | jq '.[0].Config.Env[] | select(test("password|secret"; "i"))' # Must return nothing
Network Isolation Verification
- Confirm that all expected paths work:
# nginx → dvwa: must succeed docker compose exec nginx curl -s -o /dev/null -w "%{http_code}" http://dvwa/ # dvwa → mariadb: must succeed docker compose exec dvwa mariadb-admin ping -h mariadb -u dvwauser - Confirm that forbidden paths fail:
# nginx → mariadb: must fail docker compose exec nginx mariadb-admin ping -h mariadb 2>&1Document each result in
lab08/lab08.mdwith an explanation of which network policy enforces it.
Wazuh Agent Registration
- Configure the Wazuh agent on ubuntu-server to point to the manager:
sudo WAZUH_MANAGER='10.10.10.30' \ WAZUH_AGENT_NAME='ubuntu-server' \ dpkg-reconfigure wazuh-agent sudo systemctl enable --now wazuh-agent - On the Wazuh manager (10.10.10.30), confirm the agent appears:
sudo /var/ossec/bin/agent_control -l -
In the Wazuh dashboard (
https://10.10.10.30), navigate to Agents and take a screenshot showingubuntu-serverwith status Active. - Enable the Docker Wodle in
/var/ossec/etc/ossec.confon ubuntu-server so Wazuh monitors container lifecycle events:<wodle name="docker-listener"> <interval>10m</interval> <attempts>5</attempts> <run_on_start>yes</run_on_start> <disabled>no</disabled> </wodle>Restart the agent:
sudo systemctl restart wazuh-agent - From the Wazuh dashboard, confirm at least one Docker event appears in Security Events after restarting or creating a container.
Threat Model Update
- In
lab02/threat-model.md, mark threats mitigated by secrets integration and Wazuh monitoring. Add new threats surfaced by having an agent in place (e.g., what if the agent itself is compromised?).
Deliverables
Create lab08/ in your repo containing:
- Updated
docker-compose.yml— with secrets integration applied docker inspectoutput — confirming no password in container environment- Network path tests — paste of all four
curl/mariadb-admin pingcommands and their output - Wazuh agent list —
agent_control -loutput showing ubuntu-server active - Wazuh dashboard screenshot — ubuntu-server agent status Active
- Docker event in Wazuh — screenshot of at least one Docker lifecycle event in the dashboard
- Updated
lab02/threat-model.md lab08/lab08.md— explanation of secrets approach chosen and network policy analysis
Submission
Commit all files for both parts — lab07/ and lab08/ — and push to your GitLab repo. The lab is considered submitted when the commit appears in GitLab before the due date.