# DOCKER-BP-001: Base Image Uses :latest Tag

> **Severity:** MEDIUM | **CWE:** CWE-1188

- **Language:** Docker
- **Category:** Best Practice
- **URL:** https://codepathfinder.dev/registry/docker/best-practice/DOCKER-BP-001
- **Detection:** `pathfinder scan --ruleset docker/DOCKER-BP-001 --project .`

## Description

This rule detects FROM instructions using the :latest tag (or no tag, which defaults
to :latest). Using unversioned or latest-tagged base images makes builds non-reproducible
and can introduce unexpected breaking changes or security vulnerabilities when the
upstream image is updated.

## Vulnerable Code

```python
# Bad: Uses implicit :latest tag
FROM ubuntu

# Bad: Explicit :latest tag
FROM python:latest

# Bad: Missing digest verification
FROM node:18-alpine

# Multiple stages with :latest
FROM maven:latest AS builder
FROM openjdk:latest
```

## Secure Code

```python
# Good: Pin specific version
FROM ubuntu:22.04

# Better: Use digest for cryptographic verification
FROM ubuntu:22.04@sha256:b6b83d3c331794420340093eb706a6f152d9c1fa51b262d9bf34594887c2c7ac

# Good: Pin Python minor version
FROM python:3.11.7-slim-bookworm

# Good: Pin Node.js with specific base
FROM node:18.19.0-alpine3.19

# Multi-stage with pinned versions
FROM maven:3.9.6-eclipse-temurin-17 AS builder
FROM eclipse-temurin:17.0.10_7-jre-alpine
```

## Detection Rule (Python SDK)

```python
from rules.container_decorators import dockerfile_rule
from rules.container_matchers import instruction


@dockerfile_rule(
    id="DOCKER-BP-001",
    name="Base Image Uses :latest Tag",
    severity="MEDIUM",
    cwe="CWE-1188",
    category="best-practice",
    tags="docker,dockerfile,from,image,tag,version,latest,reproducibility,best-practice,supply-chain,immutability",
    message="Base image uses ':latest' tag or no tag (defaults to latest). This makes builds non-reproducible."
)
def using_latest_tag():
    """
    Detects FROM instructions using :latest or implicit latest tag.

    Using :latest leads to non-reproducible builds as the underlying
    image can change at any time. Always pin to specific versions.
    """
    return instruction(type="FROM", image_tag="latest")
```

## How to Fix

- Pin base images to specific version tags (e.g., python:3.11-slim instead of python:latest)
- Use digest pinning (@sha256:...) for maximum reproducibility
- Document the base image version in a comment for team awareness

## FAQ

**Q: Why should I avoid the :latest tag?**

The :latest tag is mutable and can point to different images over time. Your build may break or introduce vulnerabilities when the upstream image changes without your knowledge.

**Q: What is digest pinning?**

Digest pinning uses the SHA256 hash of a specific image layer (e.g., python:3.11@sha256:abc123...). Unlike tags, digests are immutable and guarantee you always pull the exact same image.

## References

- [Docker Best Practices: Image Tagging](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/)
- [12-Factor App: Dependencies](https://12factor.net/dependencies)
- [NIST SP 800-190: Container Image Integrity](https://csrc.nist.gov/publications)
- [CIS Docker Benchmark: Section 4.1](https://www.cisecurity.org/benchmark/docker)

---

Source: https://codepathfinder.dev/registry/docker/best-practice/DOCKER-BP-001
Code Pathfinder — Open source, type-aware SAST with cross-file dataflow analysis
