Portainer CVE-2026-44883
HIGHAttack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
ReconIdentify Portainer instance behind logged reverse proxy
-
DeliveryWait for or induce operator to open container exec/shell
-
ExploitToken appears in proxy access log or Referer header
-
InstallHarvest JWT from log or attacker-controlled referer endpoint
-
C2Replay JWT against Portainer API as Authorization bearer
-
ExecuteInvoke container exec with host bind-mount on managed environment
-
ImpactExecute commands as root on Docker/Kubernetes host
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A06:2025 - Insecure Design
ASVS 5.0
V4 - API and Web Service Sensitive data in POST not GET
|
| Exploitation Conditions | Exploitation requires (1) a Portainer user with container exec, attach, or pod shell rights to first generate a |
| Impact | The CVSS 4.0 vector (AV:N/AC:H/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H) scores 7.7 High, with AC:H and UI:P correctly reflecting that exploitation is not direct: the attacker must obtain a leaked token from logs, a Referer header, or a shared URL, and a user must have generated such a URL (typically by using exec/attach features). PR:N is accurate in that the attacker themselves needs no Portainer credentials - they only need access to a leaked artifact. EPSS and CISA KEV data were not provided, and no public exploit was identified at time of analysis, so this is not currently a mass-exploitation scenario. However, real-world risk is materially higher than the AC:H suggests for organizations that ship Portainer logs to centralized SIEM/log aggregation platforms, run it behind shared reverse proxies, or whose operators navigate from Portainer to external sites - in those environments token capture is essentially passive. An administrator-token compromise yields host-level command execution on every managed cluster via container exec, so SC:N/SI:N/SA:N in the CVSS feels understated relative to the advisory's narrative impact. Prioritize patching where Portainer is internet-exposed or shares logging infrastructure with other tenants. |
| Exploit ScenarioDerived | An operator opens a browser-based container shell in Portainer, producing a WebSocket URL containing |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv3 – May 28, 2026
Token leakage in Portainer's authentication middleware allows JWT bearer tokens passed via the ?token=<JWT> URL query parameter to be harvested from reverse-proxy access logs, browser history, and HTTP Referer headers, enabling account takeover for the validity window of the token (default 8 hours). The flaw affected any user with container exec/attach rights - not just administrators - and a leaked admin token grants full control of Portainer and every managed Docker/Kubernetes environment. No public exploit identified at time of analysis, though the underlying behavior was present since JWT auth was introduced and the GitHub Security Advisory provides sufficient detail to weaponize.
Earlier versions of this analysis (2)
Authentication token leakage in Portainer container management platform allows attackers who obtain a JWT from reverse-proxy logs, browser history, or HTTP Referer headers to impersonate the legitimate user for the remainder of the token's validity (default 8 hours). The flaw stems from Portainer accepting JWTs via the ?token= URL query parameter on authenticated endpoints - a path used by browser-based container attach, exec, and pod shell features - so any user with exec/attach rights, including administrators, is exposed. No public exploit identified at time of analysis, though the vulnerability class is well-understood and trivially observable in any deployment using these features.
JWT bearer tokens leak to logs and external sites when passed via URL query parameter in Portainer's authentication middleware. Any user with container exec or attach privileges - not just administrators - exposes their authentication token through reverse-proxy access logs, browser history, and HTTP Referer headers when using Portainer's browser-based container shell features. Leaked tokens grant full user privileges for up to 8 hours (default expiration). Confirmed vendor-released patches available in versions 2.33.8, 2.39.2, and 2.41.0. No public exploit identified at time of analysis, though exploitation complexity is moderate once an attacker gains log access.
RemediationAI
Vendor-released patches are available: upgrade to Portainer 2.33.8 (LTS), 2.39.2 (LTS), or 2.41.0 (STS) per the GitHub releases at https://github.com/portainer/portainer/releases/tag/2.33.8, /2.39.2, and /2.41.0. Users on end-of-life branches (<2.33.0) must migrate to a supported LTS line. If immediate upgrade is not possible, deploy a reverse-proxy rewrite rule in nginx, Traefik, or equivalent that strips the token query parameter before requests reach Portainer - note this will break browser-based container attach, exec, and pod shell features until the patched build is deployed, since those features rely on ?token= for WebSocket upgrade in unpatched versions. Audit existing reverse-proxy and application logs for occurrences of ?token= or &token= and treat any captured JWTs as compromised by resetting the affected users' passwords (which invalidates their existing sessions) and shortening the JWT session timeout in Portainer settings to reduce the window of exposure for already-issued tokens. Operationally, instruct administrators not to share URLs containing ?token= in chat, email, or tickets, and to avoid navigating to external sites from within the Portainer UI on unpatched instances because the Referer header will carry the token.
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 1 package in go
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
Portainer is a widely deployed container management UI for Docker, Swarm, Kubernetes, Nomad, and Podman environments. The root cause is CWE-598 (Use of GET Request Method With Sensitive Query Strings): the extractBearerToken function in api/http/security/bouncer.go read the JWT from r.URL.Query().Get("token") before falling back to the Authorization header. Although Portainer scrubbed the parameter via query.Del("token") after extraction, the original URL had already been observed by upstream reverse proxies, WAFs, load balancers, access loggers, and the browser itself. The ?token= mechanism existed because browser-based WebSocket upgrade requests for container attach, exec, and pod shell features cannot easily set custom Authorization headers; the fix replaces this with the portainer_api_key HttpOnly cookie, which browsers send automatically on same-origin WebSocket upgrades. Affected packages per the GHSA are go/github.com/portainer/portainer across the 2.33.x LTS, 2.39.x LTS, and 2.40.x STS branches.
Know when Docker gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
Primary rating from Vendor (https://github.com/portainer/portainer).
CVSS VectorVendor: https://github.com/portainer/portainer
Lifecycle Timeline
2DescriptionCVE.org
Summary
Portainer's authentication middleware accepts JWT bearer tokens passed as the ?token=<JWT> URL query parameter on any authenticated API endpoint, in addition to the standard Authorization: Bearer header. URLs are recorded in reverse-proxy access logs, browser history, and HTTP Referer headers on outbound navigation, so any JWT passed this way can be harvested by anyone with access to those logs or by an external site the user subsequently visits. A leaked token grants the full privileges of the user it was issued to, until the token expires (default 8 hours, configurable).
The ?token= parameter was used by Portainer's browser-based container attach, exec, and pod shell features, so any user with exec or attach rights on a container was exposed - not only administrators.
Severity
High
Attack complexity is High because exploitation depends on the attacker obtaining a leaked token from a log, referer, or shared URL. Once obtained, a leaked token grants the privileges of the user it was issued to; for administrator tokens this compromises confidentiality, integrity, and availability of Portainer itself and of every Docker/Kubernetes environment it manages - container exec and stack deployment make host-level compromise reachable, so subsequent-system impact is also High.
Affected Versions
Query-parameter token acceptance has existed since JWT authentication was introduced in Portainer.
Fixes are included in the following releases:
| Branch | First vulnerable | Fixed in |
|---|---|---|
| 2.33.x (LTS) | 2.33.0 | 2.33.8 |
| 2.39.x (LTS) | 2.39.0 | 2.39.2 |
| 2.40.x (STS) | all prior | 2.41.0 |
Portainer releases prior to 2.33.0 are end-of-life and will not receive a fix. Users on EOL versions should upgrade to a supported LTS branch.
Workarounds
Administrators who cannot immediately upgrade can reduce exposure by:
- Stripping
?token=at the reverse proxy. A rewrite rule in nginx, Traefik, or equivalent that removes thetokenquery parameter before the request reaches Portainer blocks the query-parameter auth path entirely. Container exec and interactive shells rely on the query-parameter token for WebSocket upgrade and will stop working until the patched release is deployed. - Auditing existing logs. Search reverse-proxy access logs and application logs for
?token=or&token=occurrences and treat any captured JWT as compromised. Resetting the affected user's password invalidates their sessions; reducing the JWT session timeout in Portainer settings shortens the exposure window for tokens already issued. - Administrator hygiene. Do not share Portainer URLs that contain
?token=in chat, email, or tickets, and avoid navigating to external sites from within the Portainer UI on unpatched instances - theRefererheader will carry the token.
None of these replace the fix.
Affected Code
Pre-fix, extractBearerToken in api/http/security/bouncer.go read the JWT from the token query parameter before falling back to the Authorization header. The query.Del("token") call scrubs the parameter from r.URL.RawQuery on the way through Portainer, but by that point the original URL has already been recorded by any upstream reverse proxy, access logger, or browser.
func extractBearerToken(r *http.Request) (string, bool) {
query := r.URL.Query()
token := query.Get("token")
if token != "" {
query.Del("token")
r.URL.RawQuery = query.Encode()
return token, true
}
tokens, ok := r.Header[jwtTokenHeader]
if !ok || len(tokens) == 0 {
return "", false
}
// ...
}The fix removes the query-parameter path entirely. Authenticated requests now carry the JWT via the Authorization header for API clients, or via the portainer_api_key HttpOnly cookie for the browser UI - cookies are sent automatically on same-origin WebSocket upgrade requests, so the browser-based container attach, exec, and pod shell features continue to work without exposing the token in the URL. The WebSocket handlers that previously documented ?token= as a required query parameter have been updated to match.
Impact
- Token leakage to infrastructure. Intermediate systems that observe the request URL - reverse proxies, load balancers, access logs, WAFs, and corporate network monitoring - capture the full JWT in plaintext.
- Token leakage via the browser. URLs containing
?token=are recorded in browser history and forwarded in theRefererheader on any outbound navigation from the Portainer UI. - Account takeover. Anyone with access to a leaked JWT acts as the authenticated user for the remainder of the token's validity, without needing the password. If the leaked token belongs to an administrator, the attacker gains full API access including user management, container exec, and stack deployment.
- Reach beyond Portainer. Container exec with an administrator JWT reaches the host filesystem of managed environments and can be used to execute commands on those hosts.
Timeline
- 2026-03-06: Reported via GitHub Security Advisory by scanpwn.
- 2026-04-14: Fix merged to
develop. - 2026-04-29: 2.41.0 released.
- 2026-05-07: 2.39.2-LTS and 2.33.8-LTS released.
Credit
- scanpwn - identified and reported the query-parameter JWT acceptance and the resulting token-leakage vectors.
Executive ViewAI
Portainer JWT authentication tokens transmitted via URL query parameters can be captured from server logs, browser history, and HTTP referrer headers, creating an account takeover pathway to container management infrastructure. Theft of administrator credentials provides attackers complete control over Portainer and all dependent Docker and Kubernetes environments.
Apply vendor patch.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Information disclosure occurs when an application unintentionally exposes sensitive data that aids attackers in reconnaissance or directly compromises security.
Affected Products (CPE)CVE.org
An issue was discovered in Appsmith before 1.52. Rated critical severity (CVSS 9.8), this vulnerability is remotely expl
runc through version 1.0-rc6 (used in Docker before 18.09.2) contains a container escape vulnerability that allows attac
Netmaker makes networks with WireGuard. Rated high severity (CVSS 7.5), this vulnerability is remotely exploitable, no a
Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/
The News & Blog Designer Pack - WordPress Blog Plugin - (Blog Post Grid, Blog Post Slider, Blog Post Carousel, Blog Post
Path traversal in JFrog Artifactory (CWE-22) enables an authenticated low-privilege user to write data outside the inten
Docker 1.3.2 allows remote attackers to execute arbitrary code with root privileges via a crafted (1) image or (2) build
Remote code execution in Gogs through 0.14.2 allows authenticated users (and unauthenticated attackers on default-config
Unauthenticated remote command injection in SGWBOX N3 firmware 2.0.25 lets attackers execute arbitrary operating-system
Remote code execution in Flowise before 3.1.2 allows any authenticated user (or API caller with chatflow view/update per
Remote code execution in NocoBase Workflow Script Node (npm @nocobase/plugin-workflow-javascript) allows authenticated l
Docker Desktop Community Edition before 2.1.0.1 allows local users to gain privileges by placing a Trojan horse docker-c
Same technique Information Disclosure
View allVendor StatusVendor
SUSE
Severity: Important| Product | Status |
|---|---|
| SUSE Linux Enterprise Server 16.1 | Affected |
| SUSE Linux Enterprise Server for SAP applications 16.1 | Affected |
| SUSE Linux Enterprise Module for Package Hub 15 SP5 | Affected |
| SUSE Linux Enterprise Module for Package Hub 15 SP6 | Affected |
| openSUSE Leap 15.5 | Affected |
| openSUSE Leap 15.6 | Affected |
GHSA-jvp4-q659-95mj
NVD
CVE.org
EPSS
VulDB
Exploit-DB