OWASP Container Security
Containers package an application with everything it needs to run, so the app behaves the same on a laptop and on a server. Teams adopt them for speed and consistency. Containers also introduce new risks: vulnerable images, excessive privileges, and exposed secrets.
The Shipping Container Comparison
Global shipping uses standard metal boxes. Ports move any box with the same crane, and the contents stay sealed. A software container follows the idea. Port workers still inspect boxes for dangerous cargo, and security teams still inspect images for dangerous software.
Container Layers
+---------------------------------+ | Application code | your layer +---------------------------------+ | Libraries and runtime | your layer +---------------------------------+ | Base image (small OS files) | chosen layer +---------------------------------+ | Container runtime | platform layer +---------------------------------+ | Host operating system | platform layer +---------------------------------+ A weakness in any layer affects the running application
Key Risk Areas
| Area | Risk |
|---|---|
| Images | Old base images carry known vulnerabilities |
| Privileges | Containers running as root give attackers more power after a break-in |
| Secrets | Passwords baked into image layers stay readable |
| Registries | Untrusted public images may hide malicious code |
| Orchestration | Open dashboards or weak access rules expose the whole cluster |
| Networking | Containers talk freely to each other by default in some setups |
Build Securely
Choose Small Base Images
Minimal images contain fewer packages and fewer flaws. Distroless and slim variants remove shells and tools that attackers rely on.
Scan Images
Image scanners compare installed packages with vulnerability databases. Run scans in the build pipeline and block images that carry serious findings.
Pin and Update
Reference exact image versions, rebuild often, and keep a record of every component through a software bill of materials.
Sample Dockerfile Practices
FROM python:3.12-slim
RUN useradd --create-home appuser
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
USER appuser
CMD ["python", "app.py"]
The file uses a slim base image and switches to a non-root user before the application starts.
Run Securely
- Run containers as a non-root user.
- Drop unneeded Linux capabilities and avoid privileged mode.
- Mount the root file system as read-only when the app allows it.
- Set memory and processor limits to contain runaway processes.
- Inject secrets at runtime through a secrets manager, never through image files.
- Never mount the Docker socket into an application container.
docker run --read-only --cap-drop ALL --memory 256m \
--user 1000:1000 my-app:1.4.2
Protect the Platform
- Restrict who can pull from and push to registries.
- Sign images and verify signatures before deployment.
- Apply network policies so that containers reach only the services they need.
- Secure orchestration dashboards with strong authentication.
- Patch host systems and the container runtime promptly.
- Collect container logs centrally and alert on unusual behavior.
Scanning in the Pipeline
A strong pipeline builds the image, scans it, signs it, and only then pushes it to the registry. A failed scan stops the release and notifies the team. Schedule rescans of images already in production, because new vulnerabilities appear after deployment.
Key Takeaways
- Containers share a host, so isolation settings matter.
- Small, scanned, and regularly rebuilt images cut vulnerability exposure.
- Non-root users and dropped privileges limit damage after a break-in.
- Registry control, signing, and network policies protect the wider platform.
