Container scanning

Four ways to look at a container. One command runs all of them.

Most container scanners read a base image tag and stop. Vulnetix reads the build file, the deployment manifests, the image itself and every binary inside it, and it does the last two without a registry pull or a container daemon.

Get a free API key

A container is four different things to scan

A build file, a set of deployment manifests, a filesystem, and a pile of compiled binaries. Tools that only read one of them tell you about one of them.

Outside in

Dockerfile and Containerfile rules for running as root, unpinned base images, remote ADD, privileged builds, unpinned package installs and missing health checks.

What is declared

Compose services, Kubernetes pod templates including custom resources that embed one, Helm chart dependencies and sibling values, and packages installed by RUN lines.

Inside the image

Root filesystems and saved tars read directly, with dpkg, apk and pacman databases and per-file package ownership.

Deep inspection

ELF binaries identified by magic bytes, hashed five ways, graded for hardening and privilege, and checked for data appended past the end of the file.

A container scan stays a container scan

The command locks the engine to container rule kinds, and the lock applies to rule packs imported with --rule as well, so bringing your own rules cannot quietly turn a container check into a full source scan on a build that budgeted for one.

The image itself, without a daemon

Point the scanner at an unpacked root filesystem or a saved tar and it reads the image directly. Gzip is detected by magic bytes, one level of nested tars is flattened, which is exactly what docker save and the OCI layout produce, and path traversal is rejected before anything is written. There is no registry pull and no Docker or Podman daemon.

Installed packages come from the dpkg, apk and pacman databases. Package file lists attribute each artefact on disk to the package that installed it, so the report can say how many artefacts no OS package claims. RPM databases need a native library to read, so on a RHEL or UBI image ownership is not attempted at all rather than reporting every binary as unclaimed.

A statically linked binary still has a dependency list

A Go service copied into a scratch image has no manifest, no lockfile and no package database. It does have build metadata. Go build info is read across ELF, PE, Mach-O and XCOFF, giving the main module, every linked module with its checksum, and the toolchain reported as stdlib so it matches published advisories. Rust cargo auditable data yields every crate and the edges between them. JVM archives are resolved from Maven properties, then the manifest, then the filename, each at a lower confidence than the last, including jars nested inside a fat jar.

Nothing here executes the artefact or reads a byte of its payload. Only metadata sections are parsed, so this works offline and on an image you would never willingly run.

The binary inventory refuses to guess

Every binary hash is correlated against the CIRCL hashlookup corpus, which answers a narrow question: is this a known distribution artefact, and which one. That is provenance corroboration, not a vulnerability lookup.

The pass does no CVE matching and creates no findings. Packages compiled into binaries travel as real package identifiers and are matched there. A hashlookup package name carries no ecosystem, and string matching "openssl" across every advisory source is how a scanner starts reporting things that are not true. A malware verdict is marked on the inventory row and counted, while the finding, the triage record and the VEX statement are raised by malware scanning, which owns that chain.

What this command does not do

It does not pull from a registry and does not talk to a container daemon. Compose, Kubernetes and Helm files are parsed for components, not for misconfiguration, and there are no Kubernetes security rules in the built-in set. Build arguments and Helm template placeholders in an image reference are dropped rather than guessed, and a malformed digest is dropped rather than turned into a version. Linux file capabilities are read through getcap. Image signature verification is a separate command, and signature, attestation and transparency log sidecars are discovered during inventory generation.

Inference images inside a deployment are also read by the AI bill of materials. Packages a container installs are graded by software composition analysis, its cloud configuration by infrastructure as code scanning, and credentials baked into a layer by secrets scanning.

Read the command reference →