rastray 0.15.0

Blazing-fast static analysis CLI for security, dependency, and performance audits.
# RSTR-IAC-002 — Dockerfile `USER root`

## Summary

A Dockerfile sets `USER root` explicitly (or omits `USER` entirely)
in the final stage, so the container's PID 1 — and every application
process — runs as root. If anything inside the container escapes
(kernel CVE, mounted-host volume, privileged docker socket), the
attacker lands as root on the host.

## Severity

`High`.

## Languages

Dockerfiles, Containerfiles.

## What rastray flags

```dockerfile
FROM alpine:3.20
USER root                                          # ← flagged
CMD ["./server"]
```

## What rastray deliberately does *not* flag

- Final-stage `USER nobody` / `USER 1001` / any non-root user.
- Multi-stage builds where the *builder* stage uses root but the
  final runtime stage drops privileges.

## How to fix it

Create a non-root user and switch to it in the runtime stage:

```dockerfile
FROM alpine:3.20

RUN addgroup -S app && adduser -S app -G app
USER app

WORKDIR /home/app
COPY --chown=app:app . .
CMD ["./server"]
```

If you genuinely need root for an init step (writing to `/etc`,
binding a privileged port), do that in a builder stage or via
capabilities — not by leaving the runtime process as root:

```dockerfile
# install root-only stuff in builder stage
FROM alpine:3.20 AS builder
RUN ...   # root operations

FROM alpine:3.20
USER app
COPY --from=builder /opt/app /opt/app
```

For privileged ports (<1024) in production, terminate at a load
balancer / ingress and bind the app to a high port.

## References

- [Docker docs: USER]https://docs.docker.com/engine/reference/builder/#user
- [OWASP Container Security Cheat Sheet]https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html
- [CWE-250: Execution with Unnecessary Privileges]https://cwe.mitre.org/data/definitions/250.html