Back to Blog
Docker Engine · Authorization Bypass · CVSS 8.8

Docker AuthZ Bypass
CVE-2026-34040

A single Docker API request larger than 1 MB is truncated before the authorization plugin sees it — but the daemon runs it in full. Every AuthZ plugin is bypassed and a privileged container is born. A regression of 2024's CVE-2024-41110, and a lesson in why a control that fails open is worse than none.

Riad DAHMANIk8sec Security ResearchAugust 202613 min readDocker EngineAuthZCVE-2026-34040
Minimalist abstract hero: a breach trajectory piercing boundary rings into a core, representing a Docker authorization-plugin bypass

A Security Layer That Fails Open

Authorization plugins are how teams put a policy gate in front of the Docker Engine API — "no privileged containers", "no host mounts", "only these images". CI/CD fleets, build farms, docker-in-docker runners and management planes lean on them. CVE-2026-34040 makes that gate approve requests it never actually read.

A single Docker API request with a body larger than 1 MB is silently truncated before it reaches the AuthZ plugin — but the daemon processes the full, untruncated request. The plugin says "yes" to a harmless-looking call; the daemon runs a privileged one. CVSS 8.8, no race, no timing, works over TCP/TLS.

Vulnerability Identity Card

CVECVE-2026-34040 (incomplete-fix regression of CVE-2024-41110)
ComponentDocker Engine (dockerd) authorization-plugin (AuthZ) middleware
ClassAuthorization bypass via request-body truncation (CWE-863 / CWE-444-adjacent)
CVSS8.8 — High/Critical; single request, no interaction
ImpactBypass every AuthZ plugin → create a privileged container → host root
Fixed inDocker Engine 29.3.1 · Docker Desktop 4.66.1 (fail-closed)
MITRE ATT&CKT1211 Defense-Evasion · T1610 Deploy Container · T1611 Escape to Host
RelevanceCI/CD, build nodes, DinD runners, any daemon fronted by an AuthZ plugin

How One Big Request Wins

The Docker AuthZ flow is a middleware: an incoming API call is shown to the plugin, which returns allow/deny, and only then does the daemon act. The bug is a parsing disagreement between the two:

  • The middleware buffers the request body to forward it to the plugin, but caps that buffer at ~1 MB and forwards the truncated version.
  • The plugin makes its decision on the truncated body — which no longer contains the dangerous fields (or parses as a different, benign request).
  • The daemon then reads and executes the complete request, including the parts the plugin never saw.

Pad the request past 1 MB so the security-relevant JSON lands after the cut, and the plugin's verdict is made on a fiction.

the shape of the bypass (lab only)
# A create request whose "benign head" fits under 1MB and whose
# privileged tail (Privileged:true, host bind mounts) sits past the cut.
# Plugin approves the head; daemon executes the whole thing.
curl --unix-socket /var/run/docker.sock \
  -H "Content-Type: application/json" \
  -d @oversized-create.json \
  http://localhost/v1.45/containers/create   # AuthZ plugin: "looks fine"

Exploitation Prerequisites

Reach the APIAny path to dockerd: the socket, an exposed TCP port, a CI job, or a low-priv client the plugin was meant to constrain.
AuthZ plugin in useThe victim relies on an AuthZ plugin for policy — exactly the security-conscious shops are exposed.
Vulnerable daemonDocker Engine before 29.3.1.
No second gateNothing else stops privileged-container creation (PSP/PSA equivalent, seccomp on the socket).

From Bypass to Host

Bypassing the plugin isn't the prize — the privileged container is. Once the daemon creates one with host mounts, the container is the host:

standard privileged-container → host takeover
# inside the privileged container the attacker just got approved:
chroot /host              # host bind-mounted in via the tail of the request
# now read everything the daemon's host has:
#   ~/.aws/credentials, ~/.ssh/id_*, /etc/kubernetes/admin.conf, kubelet certs
# and persist:
echo '* * * * * root /tmp/impl' >> /host/etc/cron.d/impl

Risk Propagation

ONE HTTP request > 1 MB · no race, no timing — works over TCP/TLS API CLIENT oversized create request AUTHZ PLUGIN sees TRUNCATED body → allows it DOCKER DAEMON runs the FULL privileged request HOST root · creds kubeconfig, keys BLOCKER — upgrade to fail-closed daemon · never expose the socket · least-privilege API access
The plugin and the daemon disagree about what the request says. The plugin approves a small request; the daemon executes a big, privileged one.

The 2024 Regression

This is the same class of bug as CVE-2024-41110 from July 2024 — an AuthZ bypass that was patched, but not completely. The 2024 fix closed some vectors and left the oversized-body path open. The lesson for defenders: "we patched the AuthZ bypass last year" is not the same as "the AuthZ bypass is gone." Treat the plugin as a defense-in-depth layer, never the only control on privileged actions.

Detection

log · daemon
Create/exec API calls with request bodies > 1 MB, especially where the plugin logged an allow for a small body. High confidence.
log · runtime
A Privileged:true or host-mount container appearing when policy forbids it — the plugin's own logs will not show the dangerous fields. High.
network
dockerd API reachable over TCP (2375/2376) from unexpected sources. Medium.
audit: find privileged containers the gate should have blocked
# on each build/runner host
docker ps -q | xargs -r docker inspect \
  -f '{{.Name}} priv={{.HostConfig.Privileged}} binds={{.HostConfig.Binds}}' \
  | grep -E 'priv=true|/:|/etc|/root|/var/run/docker.sock'

Remediation

Immediate:

upgrade to the fail-closed daemon
# Docker Engine >= 29.3.1 (or Docker Desktop >= 4.66.1)
docker version --format '{{.Server.Version}}'   # must be >= 29.3.1
# the fix makes oversized bodies fail CLOSED instead of truncating past the plugin

Permanent — never let the plugin be the only wall:

  • Do not expose the Docker socket or TCP API to workloads or the network. A mounted /var/run/docker.sock is host root regardless of any CVE.
  • Prefer rootless / daemonless builds (BuildKit rootless, Buildah, Kaniko) on CI so there is no privileged daemon to bypass.
  • On Kubernetes, enforce Pod Security Admission restricted and a Kyverno/Gatekeeper rule denying privileged, hostPath, and docker.sock mounts — a control the daemon-side bypass cannot touch.
kyverno: deny docker.sock mounts and privileged pods
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata: {name: no-docker-sock-no-privileged}
spec:
  validationFailureAction: Enforce
  rules:
    - name: block-sock-and-priv
      match: {any: [{resources: {kinds: [Pod]}}]}
      validate:
        message: "docker.sock mounts and privileged containers are forbidden."
        pattern:
          spec:
            =(volumes):
              - =(hostPath):
                  path: "!/var/run/docker.sock"
            containers:
              - =(securityContext):
                  =(privileged): "false"

A control that fails open is worse than no control, because it buys false confidence. CVE-2026-34040 is a reminder that admission and authorization layers are software with parsers, and parsers disagree. Patch the daemon, yes — but the durable posture is to stop putting a privileged Docker daemon within reach of untrusted input at all, and to keep a second, independent gate (PSA + policy) that a daemon-side bypass can never disable.

— k8sec Security Research

Find every Docker daemon and socket in reach of a workload.

K8SEC surfaces exposed runtimes, docker.sock mounts and privileged pods across the fleet — the paths a daemon-side AuthZ bypass turns into host root.

Explore K8SEC

Sources: Docker security advisory and release notes for Engine 29.3.1 / Desktop 4.66.1; Cyera research disclosure; The Hacker News and eSecurity Planet reporting; CVE-2024-41110 history via CSO Online. The 1 MB truncation mechanism and fixed versions are drawn from those sources; the exploitation walkthrough is a defender-side reconstruction.

On this page

Contents

A security layer that fails openIdentity cardHow one big request winsPrerequisitesFrom bypass to hostRisk propagationThe 2024 regressionDetectionRemediationFinal word