# Portainer has a bind-mount restriction bypass via HostConfig.Mounts

Portainer's bind-mount restriction for non-admins only checked HostConfig.Binds, so users could mount any host path via HostConfig.Mounts and reach the Docker socket.

- Payout: Research
- Severity: high
- Program: Portainer
- Found by: offensiveee, alexwaira, Proscan-one, jeroengui
- Disclosed: 2026-05-14
- CVE: CVE-2026-44850
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-7fw3-x4r2-g7wc
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-7fw3-x4r2-g7wc
- Tags: area:cloud domain:cloud domain:infra impact:internal-access impact:privesc kind:research platform:ghsa sev:high tech:docker technique:source-review vuln:access-control vuln:auth-bypass vuln:privilege-escalation

**Target:** Portainer Docker API proxy, POST /containers/create
**Root cause:** The PartialContainer struct deserialized only HostConfig.Binds for the AllowBindMountsForRegularUsers check, ignoring the equivalent HostConfig.Mounts array that the Docker daemon treats identically.
**Steps:**
1. Authenticate as a regular user with container-create rights on an environment where 'Disable bind mounts for non-administrators' is enabled.
2. Send `POST /containers/create` through the Portainer proxy with a body containing `HostConfig.Mounts: [{"Type":"bind","Source":"/var/run/docker.sock","Target":"/sock"}]` instead of HostConfig.Binds.
3. The proxy's PartialContainer only parses Binds, so the request passes the check and reaches the Docker daemon.
4. Start the container and access the mounted host path (e.g. docker.sock) to read/write host filesystem as the daemon user.
**How found:** Reporter compared the container-create proxy check against the Swarm service-create check, which correctly inspects TaskTemplate.ContainerSpec.Mounts, and noticed the container-create PartialContainer struct only deserialized HostConfig.Binds.
**Exploitation:** A low-privileged authenticated user submits a container-create request with a bind-typed HostConfig.Mounts entry pointing at any host path (e.g. /etc/shadow, /root/.ssh, /var/lib/docker, /var/run/docker.sock). The mount runs as the daemon user (typically root), granting read/write to the host filesystem, other containers' state, and full Docker API access via the socket, plus persistence via authorized_keys or systemd units.
**Escalation:** Mounting /var/run/docker.sock yields full Docker API control on the host, bypassing all Portainer-level authorization above the proxy.
**Insight:** When a security control inspects a request body field, enumerate every daemon-accepted alias for that capability (Binds vs Mounts, Privileged vs DeviceRequests, etc.) — Docker's API has parallel representations and a check on one is no check at all.

