Listen to this Post
The vulnerability arises when a non-admin Portainer user has access to a Docker Swarm endpoint via RBAC. Portainer enforces seven EndpointSecuritySettings restrictions: privileged mode, host PID namespace, device mapping, capabilities, sysctls, security-opt (Seccomp/AppArmor), and bind mounts. On the standard container creation path, all seven checks are applied. However, on the Docker Swarm service API, multiple checks are missing. For POST /services/create, only 1 of 7 checks (bind mounts) is executed. The request body fields CapabilityAdd, CapabilityDrop, Sysctls, and Privileges (Seccomp/AppArmor) are not parsed because the PartialService struct lacks these fields; json.Unmarshal ignores them, and they are forwarded directly to the Docker daemon. For POST /services/{id}/update, 0 of 7 checks are applied. The route calls restrictedResourceOperation, which validates RBAC ownership but never inspects the request body or calls fetchEndpointSecuritySettings(). Additionally, the bind-mount check reads only the top-level Type field. A mount with Type: “volume” and VolumeOptions.DriverConfig.Options set to {type:”none”, o:”bind”, device:”
dailycve form:
Platform: Portainer
Version: 2.33.0-2.40.x
Vulnerability: Security restrictions bypass
Severity: Critical
date: 2026-05-07
Prediction: Already patched (2026-05-07)
What Undercode Say:
Analytics:
Check if Portainer Swarm endpoint accessible to non-admin
curl -k -H “Authorization: Bearer
Detect missing validation on service create
curl -X POST -H “Content-Type: application/json” -d ‘{“Service”:{“TaskTemplate”:{“ContainerSpec”:{“CapabilityAdd”:[“SYS_ADMIN”]}}},”Name”:”test”}’ https://portainer:9443/api/endpoints/
Detect volume driver bind bypass
curl -X POST -H “Content-Type: application/json” -d ‘{“Name”:”evil”,”Driver”:”local”,”DriverOpts”:{“type”:”none”,”o”:”bind”,”device”:”/”}}’ https://portainer:9443/api/endpoints/
Exploit:
As non-admin user, create service with ALL capabilities and host root mount
curl -X POST https://portainer:9443/api/endpoints/
Then scale to one replica and chroot into /host
Protection from this CVE:
Upgrade to fixed versions
docker run -d -p 9443:9443 portainer/portainer-ee:2.41.0 or 2.33.8/2.39.2
Workaround: revoke Swarm endpoint access for non-admin users via Portainer RBAC
Block local driver bind mounts in daemon config: add “allow-nondistributable-artifacts” or use admission controller
Isolate manager nodes: docker node update –label-add portainer.manager=true && constrain critical services
Impact:
Authenticated non-admin user gains root-equivalent code execution on Swarm manager host, ability to read Portainer database, steal secrets, escape containers, compromise entire cluster. Bypasses all configured security policies for capabilities, sysctls, seccomp, AppArmor, and bind mounts.
🎯Let’s Practice Exploiting & Learn Patching For Free:
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

