Skip to content

Conversation

@shankar-choudhury
Copy link

Summary

This PR updates every Dockerfile to use pinned image digests (e.g., debian:bookworm-slim@sha256:<digest>) instead of floating or tag-only references such as debian:bookworm-slim or ghcr.io/zaproxy/zaproxy:nightly. Unpinned base images pose a serious supply-chain security risk because upstream tags can be modified, overwritten, compromised, or drift over time. By pinning images to immutable digests, we ensure that the container build always uses the exact intended base layer, improving both security and reproducibility.

Fault/Vulnerability

Upstream Image Drift

Docker tags such as FROM debian:bookworm-slim and FROM ghcr.io/zaproxy/zaproxy:nightly are mutable references. The content of these tags can change at any time. This creates several vulnerabilities:

  1. Silent updates may introduce breaking changes or vulnerabilities.
  2. Compromised upstream registries could inject malware into official tags.
  3. Builds performed at different times produce inconsistent images.
  4. Attackers may perform tag-pinning attacks, modifying remote images while keeping the tag unchanged.

Reproducibility Failure

Floating tags mean you cannot reproduce:

  1. security scans
  2. test results
  3. SBOMs
  4. deployment compliance reports
    This conflicts with modern supply-chain frameworks like SLSA, NIST SSDF, and CIS Docker Benchmark.

Elevation of Supply-Chain Risk

An attacker who compromises a registry, they can push a backdoored image with that tag, and then the builds would automatically use it. Relying on unverified upstream content increases exposure to:

  1. malicious injection
  2. accidental corruption
  3. CVE regressions
  4. dependency rollback risks

OWASP Violations

Use a Docker image digest instead of mutable tags

Changes Made

Dockerfile-stable, Dockerfile-weekly, and Dockerfile-live

Before:
'''shell
FROM --platform=linux/amd64 debian:bookworm-slim AS builder
...
FROM debian:bookworm-slim AS final

After:
```shell
FROM --platform=linux/amd64 debian:bookworm-slim@sha256:<digest> AS builder
...
FROM debian:bookworm-slim@sha256:<digest> AS final

Both builder and final stages now use pinned Debian digests, ensuring reproducible build results and prevent tag mutation attacks and accidental upstream development drift.

Dockerfile-bare

Before:

FROM --platform=linux/amd64 debian:bookworm-slim AS builder
...
FROM eclipse-temurin:17-jre-alpine AS final

After:

FROM --platform=linux/amd64 debian:bookworm-slim@sha256:<digest> AS builder
...
FROM eclipse-temurin:17-jre-alpine@sha256:<digest> AS final

By adding digest pinning to the Debian builder image and the runtime Alpine JRE image, the image is protected from JRE tag changes, which can occur frequently.

Dockerfile-tests

Before:

FROM --platform=linux/amd64 debian:bookworm-slim AS builder
...
FROM ghcr.io/zaproxy/zaproxy:nightly

After:

FROM --platform=linux/amd64 debian:bookworm-slim@sha256:<digest> AS builder
...
FROM ghcr.io/zaproxy/zaproxy:nightly@sha256:<digest>

Both the Debian build stage and the ZAP nighly base image are now digest-pinned. Nightly builds are particularly mutable, so digest pinning prevents accidentally pulling different nightly builds, registry rollback attacks, and potentially malicious overwrite of the nightly tag.

How the Fix Works

Image digests operate like cryptographic fingerprints:

  1. They uniquely identify a specific image version
  2. They cannot change, even if tags move
  3. Docker will refuse to pull an image if the digest does not match

This ensures:

  1. Build Integrity - Every rebuild uses exactly the same upstream root filesystem.
  2. Supply Chain Protection - Even if:
    a. The registry is compromised
    b. A tag is overwritten
    c. An upstream maintainer publishes a bad release
    Your builds remain safe because they only accept the specific approved digest.

Security Impact

Eliminates entire classes of tag-based supply-chain attacks

Tag-based supply chain attacks such as:

  1. tag mutation
  2. tag rollback
  3. compromised maintainers
  4. malicious mirror injection
  5. registry poisoning
    cannot happen with immutable digests. Also, pinned digests ensure dependencies are upgraded intentionally. This means more diligence and manual upgrades, but that prevents automation attack-vectors.

…l Dockerfiles to eliminate reliance on floating upstream images and guarantee deterministic and autiable image construction, improve supply-chain integrity, and ensure fully reproducible builds.
@github-actions
Copy link

github-actions bot commented Dec 3, 2025


Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA


Posted by the CLA Assistant Lite bot.

@psiinon
Copy link
Member

psiinon commented Dec 3, 2025

Logo
Checkmarx One – Scan Summary & Details06a678dc-fa9d-49a5-bcb1-447566f13278

New Issues (3)

Checkmarx found the following issues in this Pull Request

Severity Issue Source File / Package Checkmarx Insight
MEDIUM Unpinned Package Version in Apk Add /Dockerfile-bare: 29
detailsPackage version pinning reduces the range of versions that can be installed, reducing the chances of failure due to unanticipated changes
ID: Ern784FsS3FCqyBaeaQCNvZxvtE%3D
LOW Chown Flag Exists /Dockerfile-bare: 35
detailsIt is considered a best practice for every executable in a container to be owned by the root user even if it is executed by a non-root user, only ...
ID: fJXBNB8jOZ71roVe5nGH%2F1fiKIY%3D
LOW Chown Flag Exists /Dockerfile-bare: 34
detailsIt is considered a best practice for every executable in a container to be owned by the root user even if it is executed by a non-root user, only ...
ID: 6dosJJzagw%2BSxhbVjmMWXKkHaDs%3D
Fixed Issues (45)

Great job! The following issues were fixed in this Pull Request

Severity Issue Source File / Package
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile-stable: 42
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile-live: 42
MEDIUM Apt Get Install Pin Version Not Defined /Dockerfile-weekly: 28
MEDIUM Unpinned Package Version in Apk Add /Dockerfile-bare: 28
MEDIUM Unpinned Package Version in Pip Install /Dockerfile-weekly: 54
LOW Chown Flag Exists /Dockerfile-weekly: 84
LOW Chown Flag Exists /Dockerfile-weekly: 83
LOW Chown Flag Exists /Dockerfile-weekly: 81
LOW Chown Flag Exists /Dockerfile-weekly: 85
LOW Chown Flag Exists /Dockerfile-live: 102
LOW Chown Flag Exists /Dockerfile-bare: 33
LOW Chown Flag Exists /Dockerfile-stable: 106
LOW Chown Flag Exists /Dockerfile-tests: 33
LOW Chown Flag Exists /Dockerfile-stable: 86
LOW Chown Flag Exists /Dockerfile-stable: 104
LOW Chown Flag Exists /Dockerfile-stable: 109
LOW Chown Flag Exists /Dockerfile-live: 104
LOW Chown Flag Exists /Dockerfile-stable: 110
LOW Chown Flag Exists /Dockerfile-live: 101
LOW Chown Flag Exists /Dockerfile-live: 103
LOW Chown Flag Exists /Dockerfile-live: 100
LOW Chown Flag Exists /Dockerfile-live: 107
LOW Chown Flag Exists /Dockerfile-live: 106
LOW Chown Flag Exists /Dockerfile-stable: 102
LOW Chown Flag Exists /Dockerfile-bare: 34
LOW Chown Flag Exists /Dockerfile-tests: 28
LOW Chown Flag Exists /Dockerfile-stable: 103
LOW Chown Flag Exists /Dockerfile-weekly: 89
LOW Chown Flag Exists /Dockerfile-live: 99
LOW Chown Flag Exists /Dockerfile-stable: 88
LOW Chown Flag Exists /Dockerfile-weekly: 86
LOW Chown Flag Exists /Dockerfile-stable: 105
LOW Chown Flag Exists /Dockerfile-weekly: 88
LOW Chown Flag Exists /Dockerfile-live: 98
LOW Chown Flag Exists /Dockerfile-stable: 108
LOW Chown Flag Exists /Dockerfile-weekly: 87
LOW Chown Flag Exists /Dockerfile-tests: 30
LOW Chown Flag Exists /Dockerfile-weekly: 82
LOW Chown Flag Exists /Dockerfile-live: 105
LOW Multiple RUN, ADD, COPY, Instructions Listed /Dockerfile-stable: 74
LOW Multiple RUN, ADD, COPY, Instructions Listed /Dockerfile-live: 98
LOW Multiple RUN, ADD, COPY, Instructions Listed /Dockerfile-weekly: 83
LOW Multiple RUN, ADD, COPY, Instructions Listed /Dockerfile-stable: 103
LOW RUN Instruction Using 'cd' Instead of WORKDIR /Dockerfile-live: 19
LOW RUN Instruction Using 'cd' Instead of WORKDIR /Dockerfile-tests: 16

Use @Checkmarx to reach out to us for assistance.

Just send a PR comment with @Checkmarx followed by a natural language request.

Examples: @Checkmarx how are you able to help me? @Checkmarx rescan this PR

@thc202
Copy link
Member

thc202 commented Dec 3, 2025

Please refrain from raising more PRs for the time being.

@shankar-choudhury
Copy link
Author

@thc202 Can I just submit one more PR that addresses the use of "--break-system-packages" and replaces it with commands to create a Python virtual environment to install the dependencies?

@thc202
Copy link
Member

thc202 commented Dec 3, 2025

Lets handle the existing PRs first.

@psiinon psiinon added the pending closure Probably not a bug but keeping the issue open while we get more information label Dec 4, 2025
@psiinon
Copy link
Member

psiinon commented Dec 4, 2025

While we appreciate that you mean well, turning up unannounced and raising a set of PRs which break the build is not the way to engage with a large OSS project.
The ZAP build is complex, and while your PRs may add value they also add a significant burden on us (the maintainers).
We are happy to work with you but please just focus on one problem at a time, explain what you are trying to achieve, and we will explain some of the complexities which you are probably not aware of.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pending closure Probably not a bug but keeping the issue open while we get more information Type-Task

Development

Successfully merging this pull request may close these issues.

3 participants