Dockerfile security checker
Paste a Dockerfile and get the hardening problems in it, each one mapped to the control it fails and to what an attacker gains. Nothing is uploaded: the checks run in this tab and the file never leaves your machine.
Findings
Paste a Dockerfile on the left. Results appear as you type.
What a hardened image actually is
A hardened container image is a minimal, pinned, continuously patched image that runs as an unprivileged user and ships only what the application needs at runtime. Every check here is one property of that definition, and each one closes a specific route an attacker uses after they already have code execution inside the container.
The controls come from the CIS Docker Benchmark and NIST SP 800-190, which are the two documents an auditor will hold your image against.
What this does not do
It reads text. It does not build the image, resolve the base image, or scan for known vulnerable packages, so it cannot see anything that is not written in the file you pasted.
Two consequences worth stating plainly. A base image that already declares a non-root user will still be flagged for running as root, because this tool cannot look inside it. And a clean result says the file passes these checks, not that the image is safe: for that you need a scanner such as Trivy or Grype against the built image, plus the runtime configuration, which is where most real container incidents actually begin.
Questions
- Is my Dockerfile uploaded anywhere?
- No. The checks are plain functions running in your browser tab, and there is no request to any server at any point. A Dockerfile is infrastructure source, often with hostnames, internal paths and sometimes credentials in it, so a tool that asks you to send one to a stranger is a tool worth closing.
- Why is my image flagged for running as root when the base image sets a user?
- Because this reads the text of your Dockerfile and cannot look inside the base image to see what it declares. If your base sets a non-root USER, the finding is a false positive. Adding an explicit USER instruction anyway is still worth it: it makes the runtime identity a decision someone made rather than one inherited by accident.
- Does a clean result mean the image is secure?
- No, and the difference matters. It means the file passes these checks. It says nothing about vulnerable packages inside the image, which needs a scanner such as Trivy or Grype against the built artefact, and nothing about how the container is run, which is where most real incidents start: privileged mode, a mounted Docker socket, a host path bind mount.
- Why does pinning to a digest matter if I already pin a version tag?
- A tag is a pointer and the publisher can move it. Two builds of the same Dockerfile weeks apart can therefore produce different images with no change in your repository, which is exactly the condition under which a build breaks or a vulnerability appears with nothing in your history to explain it. A digest is content-addressed and cannot move.
- Why is a secret in an ENV instruction so serious?
- Because layers are immutable and additive. Anyone who can pull the image can read every layer, and removing the value in a later instruction does not remove it from the layer that introduced it. A secret committed that way is disclosed to everyone with pull access from that moment until it is rotated.
The reasoning behind these controls is in the container hardening guide, and AiGrow is what applying them looks like on a platform that was already in production.