NEWBravos is availableCreate your account
Disclosure recordCritical

Two Portainer Advisories: Critical Bind-Mount Bypass and SSRF

Portainer published two security advisories on 8 October 2026 that credit Bugb among many independent reporters: a critical non-admin bind-mount restriction bypass (GHSA-jmr9-98g4-2phv, CVSS 9.4) and a server-side request forgery across multiple outbound features (GHSA-wqqf-pwjh-2hm6, CVSS 5.3). Both were found with Bravos, Bugb's whitebox pentesting tool, and reported privately through GitHub's security advisory process.

id
GHSA-jmr9-98g4-2phv · GHSA-wqqf-pwjh-2hm6
vendor
Portainer
severity
Critical
max cvss
9.4
credited
Shahid Parvez Hakim
published
fixed in
2.45.2 / 2.45.1
advisories
2
disclosure
Coordinated

Disclosure

  1. Reportedprivately
  2. Fixed2.45.2 / 2.45.1
  3. PublishedOct 8, 2026

Findings

The challenge

  • A default-on control (hide bind mounts for non-administrators) that was enforced by matching one exact request shape
  • A URL validator that checked a destination's syntax but not the address it resolved to
  • The same weakness classes reported independently by many researchers over several months
  • Impact bounded by how each operator deploys, segments and filters egress for Portainer

The outcome

  • GHSA-jmr9-98g4-2phv (Critical, CVSS 9.4) fixed in Portainer 2.45.2
  • GHSA-wqqf-pwjh-2hm6 (Medium, CVSS 5.3) fixed in Portainer 2.45.1
  • Bugb credited as Reporter on the bind-mount advisory and Finder on the SSRF advisory
  • Both reported privately and fixed by Portainer before public disclosure

Portainer is open-source software for running Docker and Kubernetes from a web interface. On 8 October 2026 it published two security advisories that list Bugb among the researchers credited. We found both issues with Bravos, our whitebox pentesting tool, and reported them to Portainer privately through GitHub's security advisory process. Many other researchers reported the same issues independently, and Portainer credits all of them.

Both advisories were reported privately, fixed by Portainer, and then published by Portainer.

The two advisories, in plain terms

Non-admin users could reach the host machine

GHSA-jmr9-98g4-2phv — Critical, CVSS 9.4. Fixed in Portainer 2.45.2.

Portainer has a setting, on by default, that stops users who are not administrators from mounting folders from the host machine into their containers.

The check looked for one exact wording of that request. Docker accepts other wordings that do the same thing, so a user could ask for the same mount another way and get it. With the host's files mounted, they could read and change them, and from there take control of the machine.

We reported the route through container creation. Portainer already had reports of the same flaw, so it merged ours into this advisory as a duplicate, with credit. Nineteen researchers are credited in total.

The server could be made to fetch internal addresses

GHSA-wqqf-pwjh-2hm6 — Medium, CVSS 5.3. Fixed in Portainer 2.45.1.

Several Portainer features fetch something from a web address that a user supplies, such as a Git repository.

Portainer checked that the address was well formed, but not where it pointed. A signed-in user could point the server at services inside the network that they could not reach themselves, such as a cloud provider's metadata service. How much that exposes depends on how the network around Portainer is set up.

We reported the Git repository file preview, where the response from the requested address came back inside the clone error message. Thirteen researchers are credited in total.

In both cases Portainer already had a check in place. It checked the wrong thing: the wording of a request rather than what it does, or the form of an address rather than where it leads.

What the credit means

Each advisory gathers many independent reports of the same underlying problem into one write-up. Bugb is one of the credited researchers on each.

We were not the first to report either issue. Other researchers reported the bind-mount bypass from May 2026 and the request forgery from November 2025. Portainer lists every report, ours included, in each advisory's timeline. Being credited means our report was accurate, reproducible, and reported the right way, to a maintainer who then fixed it.

How we found them with Bravos

Both issues came out of a single Bravos run, started from the command line against Portainer's open-source code. Bravos is Bugb's whitebox pentesting tool: you point it at a codebase and it works the way a careful security engineer would, end to end, without a human driving each step. Here is what it actually did, in plain terms, with the technical detail underneath for readers who want it.

Bravos first used GuardLink to read Portainer's source and write a threat model directly into the code. GuardLink follows how data moves through the application and marks every place where something a user controls reaches a sensitive action — a file mount, an outbound network request, a command — and asks one question at each: is there a control in the way, and does that control actually cover this path?

That map is what put two ordinary-looking features on the list:

  • The container-creation path, where a non-administrator supplies mount settings and a check is supposed to stop host folders from being mounted.
  • The outbound-fetch features (Git preview and similar), where the server fetches a web address the user supplies, behind a check that is supposed to validate that address.

GuardLink did not call either one a vulnerability. It flagged them as places where a control exists but might not cover everything it should — exactly the spots worth testing on a live system.

Step 2 — Rank the attack surface (CodeGraph)

Bravos then built a code graph of Portainer and ranked its entry points by what they can reach. Instead of testing thousands of routes blindly, it put the handful that lead to a mount or an outbound request at the top. This is the difference between "scan everything and hope" and "test the paths that actually matter first" — it is why two real issues surfaced quickly instead of being buried under noise.

Step 3 — Prove it on a running copy (Cert-X-Gen)

A threat model says what could be wrong. It is not proof. So Bravos stood up a running copy of Portainer and used Cert-X-Gen to test each flagged path against the live application — and to only call something confirmed when the app's own behaviour demonstrated it:

  • The bind-mount control: the check matched one exact wording of a mount request. Cert-X-Gen submitted the same mount described another way that Docker accepts equally — and the host folder mounted. The control was matching the wording of a request, not what the request does. Confirmed by the mount actually happening, not by reading the code.
  • The address check: the validator confirmed an address was well formed but never checked where it led. Cert-X-Gen pointed the server at an internal-only address and watched the response come back inside the clone error message. Confirmed by the server actually fetching something it should never reach.

In both cases the same pattern showed up: a control that checked the shape of the input (the wording of a request, the form of an address) instead of its effect (what it mounts, where it leads).

Step 4 — Report only what was proven

Bravos does not report a guess as a finding. Each issue reached the report only after Cert-X-Gen observed the app behave the way the threat model predicted. We then sent each result to Portainer privately, through GitHub's security advisory process, and published this write-up only after Portainer had shipped fixes and the advisories were public.

The point is the shape of the run: map the code, rank what matters, prove it on a live copy, report only what is proven. One command, no human stepping through it — and two real issues in a widely deployed open-source tool, reported the right way.

If you run Portainer

  • Upgrade to 2.45.2. It carries the fixes for both advisories.
  • On the 2.39.x long-term support line, the bind-mount advisory notes the fix was not yet released for that line when it was published. Follow its workarounds until it is.
  • Limit what the Portainer server can reach. Block its outbound access to the cloud metadata address (169.254.169.254) and to internal ranges it has no reason to contact. The new destination controls for the request forgery are off by default, and only Portainer Business Edition can enable them.

Each advisory lists its full workarounds. Read them for the details that fit your deployment.

References

Everything in this case study comes from Portainer's published advisories.

Focus areas

Docker and Swarm SecurityServer-Side Request Forgery (SSRF)Container Escape and Host Filesystem AccessWhitebox Pentesting with Bravos

Recognition

  • Credited in Portainer Security Advisory GHSA-jmr9-98g4-2phv
  • Credited in Portainer Security Advisory GHSA-wqqf-pwjh-2hm6

Test your own code the same way.

Bravos writes a threat model into your code, then tests a running copy to confirm each threat.