# CL-0011: Dangerous Capabilities Added

**Severity:** HIGH (CRITICAL when `cap_add: ALL` is used)

**References:**
- [OWASP Docker Security Rule #3](https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-3-limit-capabilities-grant-only-specific-capabilities-needed-by-a-container)
- CIS Docker Benchmark 5.4 — Ensure that Linux kernel capabilities are restricted within containers

## What it detects

Services that add dangerous Linux capabilities via `cap_add`:

| Capability | Severity | Risk |
|-----------|----------|------|
| `ALL` | CRITICAL | Grants every Linux capability — functionally disables capability-based isolation |
| `SYS_ADMIN` | HIGH | Near-root access: mount filesystems, configure namespaces, BPF |
| `SYS_PTRACE` | HIGH | Trace/inspect any process, read secrets from memory |
| `NET_ADMIN` | HIGH | Modify routing tables, firewall rules, sniff traffic |
| `SYS_MODULE` | HIGH | Load/unload kernel modules |
| `SYS_RAWIO` | HIGH | Raw I/O port access (iopl/ioperm) |
| `SYS_TIME` | HIGH | Change system clock, affecting all containers and the host |
| `SYS_BOOT` | HIGH | Reboot the host or load a new kernel via kexec |
| `DAC_READ_SEARCH` | HIGH | Bypass file read permission checks on the host |
| `DAC_OVERRIDE` | HIGH | Bypass all file read, write, and execute permission checks |
| `BPF` | HIGH | Load BPF programs — arbitrary kernel read/write on modern kernels |

Safe capabilities like `NET_BIND_SERVICE` or `CHOWN` are not flagged. `PERFMON` is not yet on the dangerous list. `MKNOD` and `SYS_CHROOT` are intentionally not flagged here because the `cap_drop: [ALL]` baseline (CL-0006) already covers them; adding them back is not on its own a HIGH-severity escape path.

## Why it matters

Linux capabilities split root's privileges into discrete units. Adding dangerous capabilities — especially `SYS_ADMIN` — grants powers that can be chained into container escapes. `SYS_ADMIN` alone enables `mount()`, `unshare()`, and BPF operations that are well-documented escape paths. `cap_add: ALL` undoes capability isolation entirely and is treated as functionally equivalent to `privileged: true` (CL-0002) for severity purposes.

## Fix

Remove the dangerous capability and evaluate whether the workload truly requires it:

```yaml
# Before
services:
  app:
    image: myapp:1.0
    cap_add:
      - SYS_ADMIN

# After — drop all, add back only what's needed
services:
  app:
    image: myapp:1.0
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE
```

If a dangerous capability is genuinely required (e.g., `SYS_PTRACE` for a debugger sidecar), document the justification and consider running the workload outside a container.

## When to suppress

- `NET_ADMIN` for VPN/networking containers (Tailscale, WireGuard, OpenVPN) — required to manage the tun device and routing tables. Suppress with a `reason:` naming the network workload.
- `SYS_PTRACE` for a debugger or profiler sidecar that you trust and that runs alongside the workload it inspects.

Do not suppress `cap_add: ALL` — there is no legitimate use case for granting every capability rather than enumerating the specific ones needed.

## See also

- [CL-0002](CL-0002.md) — `privileged: true` (functional superset of `cap_add: ALL`)
- [CL-0006](CL-0006.md) — `cap_drop: [ALL]` baseline (drops the defaults this rule's `cap_add` re-grants)
