Cloud Security

Your Container Image Contains a Package Manager an Attacker Can Use

Key takeaway: Every binary in an image is a tool available to an attacker who achieves execution. Removing what the application does not need eliminates capability rather than merely patching it.

What a Default Image Provides

Building on a general-purpose base image produces a container containing a shell, curl or wget, a package manager, ps and netstat, and several hundred libraries.

An attacker who gains execution inside that container has a complete working environment. They can download tooling, install packages, enumerate the network and pivot — all using software you shipped.

Removing those binaries does not fix the vulnerability that allowed execution. It substantially reduces what execution is worth.

Comparing Base Images

Base Approximate size Contents CVE surface
Full distribution 700 MB+ Everything Large
Slim variant 80–120 MB Reduced Moderate
Alpine 5–15 MB Busybox, apk Small
Distroless 2–20 MB Runtime only, no shell Very small
Static scratch Binary only Nothing else Minimal

Distroless images contain the language runtime and its dependencies with no shell, no package manager and no utilities. For compiled languages, a static binary on scratch goes further — the image contains one file.

The vulnerability count difference is dramatic and mostly reflects removed packages rather than fixed ones. A scanner reporting two hundred findings on a full base image and three on distroless is describing the same application; the difference is everything that was not needed.

The Operational Objection

The standard resistance is that debugging requires a shell. This is a real concern with a good answer.

Ephemeral debug containers attach a separate image containing your tooling to a running pod’s namespaces, giving full diagnostic capability without that tooling being resident in the production image. The debug container exists for the duration of the investigation and then disappears.

That arrangement is strictly better than a permanent shell, because the capability is available on demand to authorised operators rather than continuously to anyone who achieves execution.

Comprehensive logging and metrics reduce the need for interactive debugging in the first place. Teams that reach for a shell frequently are usually compensating for insufficient instrumentation.

Other Hardening That Matters

Run as a non-root user with an explicit numeric UID, and set the filesystem to read-only with writable volumes only where genuinely required. Drop all Linux capabilities and add back only what the process needs — most applications need none.

Multi-stage builds are the mechanism that makes minimal images practical. Compile with a full toolchain in the build stage, copy only the resulting artefact into a minimal runtime stage. Build dependencies never reach production.

Pin base images by digest rather than tag. A tag is mutable, so :3.12 today and tomorrow may be different images, which defeats reproducibility.

The Bottom Line

Use distroless or static base images with multi-stage builds, run as non-root with a read-only filesystem and no capabilities, and pin by digest. Handle debugging with ephemeral containers rather than by shipping a shell.

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button