# DOCKER-BP-005: apt-get Without --no-install-recommends

> **Severity:** LOW | **CWE:** CWE-710

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

## Description

This rule detects RUN instructions that use `apt-get install` without the
`--no-install-recommends` flag. By default, apt installs both required packages
and "recommended" packages, which are often unnecessary and significantly bloat
Docker images, increasing attack surface and build/deploy times.

## Vulnerable Code

```python
FROM ubuntu:22.04

# Bad: Installs nginx + 50+ recommended packages
RUN apt-get update && \
    apt-get install -y nginx curl

# This pulls in:
# - X11 libraries (for desktop apps, not needed in containers)
# - Documentation packages
# - Example/demo files
# - Optional utilities
```

## Secure Code

```python
FROM ubuntu:22.04

# Good: Only install required packages
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
      nginx \
      curl \
      ca-certificates && \
    # Clean up apt cache to further reduce size
    rm -rf /var/lib/apt/lists/*

# Result: Smaller, more secure image
```

## Detection Rule (Python SDK)

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


@dockerfile_rule(
    id="DOCKER-BP-005",
    name="apt-get Without --no-install-recommends",
    severity="LOW",
    cwe="CWE-710",
    category="best-practice",
    tags="docker,dockerfile,apt-get,package-manager,ubuntu,debian,optimization,image-size,best-practice,bloat,attack-surface",
    message="apt-get install without --no-install-recommends. This installs unnecessary packages, increasing image size and attack surface."
)
def apt_without_no_recommends():
    """
    Detects apt-get install without --no-install-recommends flag.

    Without this flag, apt installs "recommended" packages which are
    often not needed and bloat the image by 30-50%.
    """
    return all_of(
        instruction(type="RUN", contains="apt-get install"),
        instruction(type="RUN", not_contains="--no-install-recommends")
    )
```

## How to Fix

- Use apt-get instead of apt in Dockerfiles for stable CLI behavior
- Always run apt-get update && apt-get install in the same RUN instruction
- Add --no-install-recommends to minimize installed packages
- Clean up with rm -rf /var/lib/apt/lists/* in the same layer

## Security Implications

- **Supply Chain Risks:** Recommended packages may pull in: - Unmaintained dependencies - Packages from less-trusted sources - Transitive dependencies with vulnerabilities
- **Compliance Issues:** - More packages = more licenses to track - Harder to maintain Software Bill of Materials (SBOM) - Difficult to audit all dependencies

## FAQ

**Q: Why use apt-get instead of apt?**

apt is designed for interactive use and its output format may change between versions. apt-get provides a stable CLI interface suitable for scripting and Dockerfiles.

**Q: Why combine update and install in one RUN?**

Docker caches layers. If apt-get update is in a separate RUN, the package index cache may be stale when install runs, causing package-not-found errors.

## References

- [Debian Policy Manual: Dependencies](https://www.debian.org/doc/debian-policy/ch-relationships.html)
- [Docker Best Practices: Minimize Layer Size](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/)
- [Ubuntu Package Management Guide](https://help.ubuntu.com/community/AptGet/Howto)
- [CIS Docker Benchmark: Image Optimization](https://www.cisecurity.org/benchmark/docker)

---

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