Skip to content

no-unsafe-build-features

A # syntax= line makes BuildKit run a container as your Dockerfile frontend. Which frontends are safe to use, and why RUN --network=host and --security=insecure weaken the build.

On this page

A # syntax= line at the top of a Dockerfile names a container image. BuildKit pulls that image and runs it as the frontend that turns your Dockerfile into a build. Whatever you name there runs as part of your build. This rule reports a # syntax= line that selects a frontend outside the official set. It trusts docker/dockerfile and docker/dockerfile-upstream on Docker Hub, with any tag, so docker/dockerfile:1 and docker/dockerfile:1.7-labs pass. A third-party frontend pinned by digest, such as registry.example.com/team/frontend@sha256:…, passes too, because you reviewed one exact artifact. A registry-qualified look-alike such as ghcr.io/docker/dockerfile is reported. BuildKit reads the directive only from the comment lines at the very top of the file. A # syntax= line after a blank line, a plain comment or an instruction does nothing, and the rule ignores it.

The rule also reports RUN --security=insecure and RUN --network=host. Both flags remove isolation from one build step. The rule reads only the flags that come right after RUN, so RUN docker run --network=host app passes.

What the rule catches

Dockerfile with a third-party frontend and two RUN steps that drop isolation
# syntax=ghcr.io/example/dockerfile-frontend:latest
FROM debian:12-slim
RUN --security=insecure make install
RUN --network=host ./fetch-assets.sh

Scanning this file reports:

⚠ WARN [docker-doctor/no-unsafe-build-features]
  Dockerfile selects BuildKit frontend 'ghcr.io/example/dockerfile-frontend:latest'. A frontend runs with access to the build, so an untrusted one can read or change what it builds.

Why it matters

A frontend is not a parser that reads your file and stays out of the way. It is a container that BuildKit runs during the build, and it talks to BuildKit over an API. Two BuildKit advisories show what that costs when the frontend is not one you trust. CVE-2026-33747 let a custom frontend craft an API message that wrote files outside BuildKit's state directory. The advisory says the issue needs an untrusted frontend set with #syntax or --build-arg BUILDKIT_SYNTAX, and that a well-known frontend image such as docker/dockerfile is not affected. The fix shipped in BuildKit v0.28.1. CVE-2026-61711 let a custom frontend send a crafted build request that turned off Seccomp and AppArmor for the build container, even when the user had not allowed the security.insecure entitlement. The fix shipped in BuildKit v0.31.1. The advisory's workaround is to use only frontends from trusted providers.

The RUN flags are the same trade made on purpose. --security=insecure runs the step without the sandbox, and --network=host shares the host's network with it. A build step that needs either one can reach more of the machine than a normal step can, so each one deserves a second look.

How to fix it

Use the official docker/dockerfile frontend, or pin a third-party one by digest after reviewing it. Remove --security=insecure and --network=host unless the build truly needs them.

Dockerfile with the official frontend and a sandboxed RUN step
# syntax=docker/dockerfile:1
FROM python:3.12-slim
RUN --mount=type=cache,target=/root/.cache/pip pip install -r requirements.txt

Use the official frontend unless you have a reason not to:

# syntax=docker/dockerfile:1

If you need a third-party frontend, review it and pin the exact image by digest. A tag can move, a digest cannot.

BuildKit lets you set a frontend outside the Dockerfile too, with --build-arg BUILDKIT_SYNTAX=…. That value is not in the file, so this rule cannot see it. Check your build scripts and CI for it.

--security=insecure and --network=host need the matching entitlements on the builder (--allow security.insecure, --allow network.host). If a build step needs one of them, keep it in a dedicated build and leave it out of the Dockerfile you publish.

Rule details

  • Rule key — docker-doctor/no-unsafe-build-features
  • Category — Security
  • Default severity — warning
  • Applies to — Dockerfiles

Explain this rule from the CLI:

npx @docker-doctor/cli@latest rules explain docker-doctor/no-unsafe-build-features

Change its severity — or turn it off — in your config file:

// docker-doctor.config.ts
export default {
  rules: {
    "docker-doctor/no-unsafe-build-features": "off",
  },
};

Severity affects the health score: error findings cost more points than warning, and info costs the least.