CWE-863
Allowed-with-ReviewIncorrect Authorization
Abstraction: Class · Status: Incomplete
The product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check.
5537 vulnerabilities reference this CWE, most recent first.
GHSA-MG6F-MX33-MRJ2
Vulnerability from github – Published: 2022-08-18 00:00 – Updated: 2024-09-17 03:30Improper Access Control vulnerability in the /Exago/WrImageResource.adx route as used in Device42 Asset Management Appliance allows an unauthenticated attacker to read sensitive server files with root permissions. This issue affects: Device42 CMDB versions prior to 18.01.00.
{
"affected": [],
"aliases": [
"CVE-2022-1401"
],
"database_specific": {
"cwe_ids": [
"CWE-863"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-08-17T00:15:00Z",
"severity": "HIGH"
},
"details": "Improper Access Control vulnerability in the /Exago/WrImageResource.adx route as used in Device42 Asset Management Appliance allows an unauthenticated attacker to read sensitive server files with root permissions. This issue affects: Device42 CMDB versions prior to 18.01.00.",
"id": "GHSA-mg6f-mx33-mrj2",
"modified": "2024-09-17T03:30:41Z",
"published": "2022-08-18T00:00:19Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-1401"
},
{
"type": "WEB",
"url": "https://www.bitdefender.com/blog/labs/a-red-team-perspective-on-the-device42-asset-management-appliance"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-MG85-W8WC-5FVP
Vulnerability from github – Published: 2022-05-24 19:17 – Updated: 2022-07-06 00:00The Brizy Page Builder plugin <= 2.3.11 for WordPress used an incorrect authorization check that allowed any logged-in user accessing any endpoint in the wp-admin directory to modify the content of any existing post or page created with the Brizy editor. An identical issue was found by another researcher in Brizy <= 1.0.125 and fixed in version 1.0.126, but the vulnerability was reintroduced in version 1.0.127.
{
"affected": [],
"aliases": [
"CVE-2021-38345"
],
"database_specific": {
"cwe_ids": [
"CWE-79",
"CWE-863"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-10-14T16:15:00Z",
"severity": "HIGH"
},
"details": "The Brizy Page Builder plugin \u003c= 2.3.11 for WordPress used an incorrect authorization check that allowed any logged-in user accessing any endpoint in the wp-admin directory to modify the content of any existing post or page created with the Brizy editor. An identical issue was found by another researcher in Brizy \u003c= 1.0.125 and fixed in version 1.0.126, but the vulnerability was reintroduced in version 1.0.127.",
"id": "GHSA-mg85-w8wc-5fvp",
"modified": "2022-07-06T00:00:30Z",
"published": "2022-05-24T19:17:35Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-38345"
},
{
"type": "WEB",
"url": "https://www.wordfence.com/blog/2021/10/multiple-vulnerabilities-in-brizy-page-builder-plugin-allow-site-takeover"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-MG95-QW85-JRQ5
Vulnerability from github – Published: 2022-05-24 19:17 – Updated: 2022-07-13 00:01The software logistics system of SAP NetWeaver AS ABAP and ABAP Platform versions - 700, 701, 702, 710, 730, 731, 740, 750, 751, 752, 753, 754, 755, 756, enables a malicious user to transfer ABAP code artifacts or content, by-passing the established quality gates. By this vulnerability malicious code can reach quality and production, and can compromise the confidentiality, integrity, and availability of the system and its data.
{
"affected": [],
"aliases": [
"CVE-2021-38178"
],
"database_specific": {
"cwe_ids": [
"CWE-863"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-10-12T15:15:00Z",
"severity": "HIGH"
},
"details": "The software logistics system of SAP NetWeaver AS ABAP and ABAP Platform versions - 700, 701, 702, 710, 730, 731, 740, 750, 751, 752, 753, 754, 755, 756, enables a malicious user to transfer ABAP code artifacts or content, by-passing the established quality gates. By this vulnerability malicious code can reach quality and production, and can compromise the confidentiality, integrity, and availability of the system and its data.",
"id": "GHSA-mg95-qw85-jrq5",
"modified": "2022-07-13T00:01:34Z",
"published": "2022-05-24T19:17:19Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-38178"
},
{
"type": "WEB",
"url": "https://launchpad.support.sap.com/#/notes/3097887"
},
{
"type": "WEB",
"url": "https://wiki.scn.sap.com/wiki/pages/viewpage.action?pageId=587169983"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-MGFP-F8W4-CFPF
Vulnerability from github – Published: 2021-12-08 00:01 – Updated: 2022-08-10 00:00An improper authorization control vulnerability exists in Ivanti Avalanche before 6.3.3 allows an attacker with access to the Inforail Service to perform privilege escalation.
{
"affected": [],
"aliases": [
"CVE-2021-42126"
],
"database_specific": {
"cwe_ids": [
"CWE-863"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-12-07T14:15:00Z",
"severity": "HIGH"
},
"details": "An improper authorization control vulnerability exists in Ivanti Avalanche before 6.3.3 allows an attacker with access to the Inforail Service to perform privilege escalation.",
"id": "GHSA-mgfp-f8w4-cfpf",
"modified": "2022-08-10T00:00:22Z",
"published": "2021-12-08T00:01:33Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-42126"
},
{
"type": "WEB",
"url": "https://forums.ivanti.com/s/article/Security-Alert-CVE-s-Addressed-in-Avalanche-6-3-3"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-MGH9-4MWP-FG55
Vulnerability from github – Published: 2025-08-18 21:00 – Updated: 2025-08-29 20:35Overview
OpenFGA v1.9.3 to v1.9.4 ( openfga-0.2.40 <= Helm chart <= openfga-0.2.41, v1.9.3 <= docker <= v.1.9.4) are vulnerable to improper policy enforcement when certain Check and ListObject calls are executed.
Am I Affected?
You are affected by this vulnerability if you are using OpenFGA v1.9.3 to v1.9.4, specifically under the following preconditions: - Calling Check API or ListObjects with an authorization model that has a relationship directly assignable by more than 1 userset with same type, and - There are check or list object queries that rely on the above relationship, and - You have userset tuples that are assigned to the above relationship
Fix
Upgrade to v1.9.5. This upgrade is backwards compatible.
Workaround
Downgrade to v1.9.2 with enable-check-optimizations removed from OPENFGA_EXPERIMENTALS
Acknowledgments
OpenFGA would like Dominic Harries and rrozza-apolitical to thank for discovering this vulnerability.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/openfga/openfga"
},
"ranges": [
{
"events": [
{
"introduced": "1.9.3"
},
{
"fixed": "1.9.5"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-55213"
],
"database_specific": {
"cwe_ids": [
"CWE-863"
],
"github_reviewed": true,
"github_reviewed_at": "2025-08-18T21:00:52Z",
"nvd_published_at": "2025-08-18T20:15:29Z",
"severity": "MODERATE"
},
"details": "### Overview\nOpenFGA v1.9.3 to v1.9.4 ( openfga-0.2.40 \u003c= Helm chart \u003c= openfga-0.2.41, v1.9.3 \u003c= docker \u003c= v.1.9.4) are vulnerable to improper policy enforcement when certain Check and ListObject calls are executed.\n\n### Am I Affected?\nYou are affected by this vulnerability if you are using OpenFGA v1.9.3 to v1.9.4, specifically under the following preconditions:\n- Calling Check API or ListObjects with an [authorization model](https://openfga.dev/docs/concepts#what-is-an-authorization-model) that has a relationship directly assignable by more than 1 [userset](https://openfga.dev/docs/modeling/building-blocks/usersets) with same [type](https://openfga.dev/docs/concepts#what-is-a-type), and\n- There are check or list object queries that rely on the above relationship, and\n- You have userset tuples that are assigned to the above relationship\n\n\n### Fix\nUpgrade to v1.9.5. This upgrade is backwards compatible.\n\n### Workaround\nDowngrade to v1.9.2 with enable-check-optimizations removed from OPENFGA_EXPERIMENTALS\n\n### Acknowledgments\nOpenFGA would like Dominic Harries and rrozza-apolitical to thank for discovering this vulnerability.",
"id": "GHSA-mgh9-4mwp-fg55",
"modified": "2025-08-29T20:35:56Z",
"published": "2025-08-18T21:00:52Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/openfga/openfga/security/advisories/GHSA-mgh9-4mwp-fg55"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-55213"
},
{
"type": "WEB",
"url": "https://github.com/openfga/openfga/commit/1a7e0e37fc4777c824b2386cac4867a66f3480b0"
},
{
"type": "PACKAGE",
"url": "https://github.com/openfga/openfga"
},
{
"type": "WEB",
"url": "https://pkg.go.dev/vuln/GO-2025-3894"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:N/VI:N/VA:N/SC:H/SI:H/SA:H",
"type": "CVSS_V4"
}
],
"summary": "OpenFGA Authorization Bypass "
}
GHSA-MGPH-G68W-QPM4
Vulnerability from github – Published: 2022-05-24 17:36 – Updated: 2022-05-24 17:36In AndroidManifest.xml, there is a possible permissions bypass. This could lead to local escalation of privilege allowing a non-system app to send a broadcast it shouldn't have permissions to send, with no additional execution privileges needed. User interaction is not needed for exploitation.Product: AndroidVersions: Android-11Android ID: A-157472962
{
"affected": [],
"aliases": [
"CVE-2020-0481"
],
"database_specific": {
"cwe_ids": [
"CWE-863"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2020-12-15T16:15:00Z",
"severity": "LOW"
},
"details": "In AndroidManifest.xml, there is a possible permissions bypass. This could lead to local escalation of privilege allowing a non-system app to send a broadcast it shouldn\u0027t have permissions to send, with no additional execution privileges needed. User interaction is not needed for exploitation.Product: AndroidVersions: Android-11Android ID: A-157472962",
"id": "GHSA-mgph-g68w-qpm4",
"modified": "2022-05-24T17:36:25Z",
"published": "2022-05-24T17:36:25Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2020-0481"
},
{
"type": "WEB",
"url": "https://source.android.com/security/bulletin/pixel/2020-12-01"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-MGPV-62W8-P4RP
Vulnerability from github – Published: 2026-03-29 15:30 – Updated: 2026-03-29 15:30OpenClaw before 2026.3.11 contains an authorization bypass vulnerability allowing authenticated operators with only operator.write permission to access admin-only browser profile management routes through browser.request. Attackers can create or modify browser profiles and persist attacker-controlled remote CDP endpoints to disk without holding operator.admin privileges.
{
"affected": [],
"aliases": [
"CVE-2026-32972"
],
"database_specific": {
"cwe_ids": [
"CWE-863"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-03-29T13:17:01Z",
"severity": "HIGH"
},
"details": "OpenClaw before 2026.3.11 contains an authorization bypass vulnerability allowing authenticated operators with only operator.write permission to access admin-only browser profile management routes through browser.request. Attackers can create or modify browser profiles and persist attacker-controlled remote CDP endpoints to disk without holding operator.admin privileges.",
"id": "GHSA-mgpv-62w8-p4rp",
"modified": "2026-03-29T15:30:19Z",
"published": "2026-03-29T15:30:19Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/openclaw/openclaw/security/advisories/GHSA-vmhq-cqm9-6p7q"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-32972"
},
{
"type": "WEB",
"url": "https://www.vulncheck.com/advisories/openclaw-authorization-bypass-in-browser-profile-management-via-browser-request"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
]
}
GHSA-MGQ6-4X29-88R3
Vulnerability from github – Published: 2026-05-14 16:24 – Updated: 2026-06-09 10:25Summary
Portainer proxies requests to Kubernetes clusters through a middleware layer (kubeClientMiddleware) that validates the requesting user's token before forwarding traffic to the cluster. When security.RetrieveTokenData returned an error, the middleware wrote an HTTP 403 response but was missing a return statement — execution continued into the handler with a nil tokenData value.
The Kubernetes endpoints sit behind Portainer's outer AuthenticatedAccess bouncer, so an attacker requires a valid Portainer session. However, a user whose secondary token validation fails in kubeClientMiddleware — for example a user without permission to access a given Kubernetes endpoint — would have their request forwarded to the cluster anyway, bypassing the authorization check. The same defect was present in both the CE and EE codebases.
Severity
High CWE-863 — Incorrect Authorization
Privilege required is Low — any valid Portainer session is sufficient to reach the middleware. Once the authorization outcome is bypassed, the attacker can read and modify Kubernetes resources on the target endpoint that their role should not permit — confidentiality and integrity impact are both High. No availability impact is introduced directly.
Affected Versions
The missing return statement has been present since Kubernetes proxy support was introduced.
| Branch | First vulnerable | Fixed in |
|---|---|---|
| 2.33.x (LTS) | 2.33.0 | 2.33.8 |
Portainer 2.39.0 and later are not affected — the fix was present from the initial 2.39.0 release. All 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 release.
Workarounds
There is no configuration change that prevents the bypass directly. Administrators who cannot immediately upgrade can reduce exposure by:
- Restricting Kubernetes endpoint access. Remove Portainer access to Kubernetes endpoints for users who do not require it. A user without endpoint access cannot reach
kubeClientMiddleware. - Auditing Kubernetes RBAC. Ensure the service account Portainer uses to proxy cluster requests carries least-privilege RBAC permissions — this limits the blast radius if the bypass is exploited.
Neither of these replaces the fix.
Affected Code
kubeClientMiddleware in api/http/handler/kubernetes/handler.go wrote the error response but did not return, allowing execution to continue with nil tokenData:
// api/http/handler/kubernetes/handler.go (pre-fix — CE and EE)
tokenData, err := security.RetrieveTokenData(r)
if err != nil {
httperror.WriteError(w, http.StatusForbidden,
"permission denied to access the environment", err)
// missing return — tokenData is nil, execution continues
}
// tokenData.ID dereferenced on the next line:
_, ok := handler.KubernetesClientFactory.GetProxyKubeClient(
strconv.Itoa(endpointID), strconv.Itoa(int(tokenData.ID)))
The fix adds a single return after the WriteError call in both CE and EE:
// post-fix
if err != nil {
httperror.WriteError(w, http.StatusForbidden,
"permission denied to access the environment", err)
return
}
Impact
- Kubernetes authorization bypass. A low-privileged Portainer user can reach Kubernetes API endpoints on environments their role does not permit, with the proxy client of the legitimate session used as the vehicle.
- Cluster resource access. Depending on the service account permissions Portainer holds on the cluster, the attacker can read or modify namespaced resources — including pods, secrets, config maps, and deployments.
- Potential for lateral movement. Kubernetes secrets readable through this path may contain credentials for other services within the cluster or the broader infrastructure.
Timeline
- 2026-02-16: Fix merged to develop.
- 2026-02-25: 2.39.0 released with fix.
- 2026-05-07: 2.33.8 released with backport fix.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/portainer/portainer"
},
"ranges": [
{
"events": [
{
"introduced": "2.33.0"
},
{
"fixed": "2.33.8"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-44882"
],
"database_specific": {
"cwe_ids": [
"CWE-863"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-14T16:24:29Z",
"nvd_published_at": "2026-05-28T22:16:59Z",
"severity": "HIGH"
},
"details": "## Summary\n\nPortainer proxies requests to Kubernetes clusters through a middleware layer (`kubeClientMiddleware`) that validates the requesting user\u0027s token before forwarding traffic to the cluster. When `security.RetrieveTokenData` returned an error, the middleware wrote an HTTP 403 response but was missing a `return` statement \u2014 execution continued into the handler with a nil `tokenData` value.\n\nThe Kubernetes endpoints sit behind Portainer\u0027s outer `AuthenticatedAccess` bouncer, so an attacker requires a valid Portainer session. However, a user whose secondary token validation fails in `kubeClientMiddleware` \u2014 for example a user without permission to access a given Kubernetes endpoint \u2014 would have their request forwarded to the cluster anyway, bypassing the authorization check. The same defect was present in both the CE and EE codebases.\n\n## Severity\n\n**High**\n**CWE-863** \u2014 Incorrect Authorization\n\nPrivilege required is Low \u2014 any valid Portainer session is sufficient to reach the middleware. Once the authorization outcome is bypassed, the attacker can read and modify Kubernetes resources on the target endpoint that their role should not permit \u2014 confidentiality and integrity impact are both High. No availability impact is introduced directly.\n\n## Affected Versions\n\nThe missing `return` statement has been present since Kubernetes proxy support was introduced.\n\n| Branch | First vulnerable | Fixed in |\n|--------------|------------------|------------|\n| 2.33.x (LTS) | 2.33.0 | **2.33.8** |\n\nPortainer 2.39.0 and later are not affected \u2014 the fix was present from the initial 2.39.0 release. All 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 release.\n\n## Workarounds\n\nThere is no configuration change that prevents the bypass directly. Administrators who cannot immediately upgrade can reduce exposure by:\n\n- **Restricting Kubernetes endpoint access.** Remove Portainer access to Kubernetes endpoints for users who do not require it. A user without endpoint access cannot reach `kubeClientMiddleware`.\n- **Auditing Kubernetes RBAC.** Ensure the service account Portainer uses to proxy cluster requests carries least-privilege RBAC permissions \u2014 this limits the blast radius if the bypass is exploited.\n\nNeither of these replaces the fix.\n\n## Affected Code\n\n`kubeClientMiddleware` in `api/http/handler/kubernetes/handler.go` wrote the error response but did not return, allowing execution to continue with nil `tokenData`:\n\n```go\n// api/http/handler/kubernetes/handler.go (pre-fix \u2014 CE and EE)\ntokenData, err := security.RetrieveTokenData(r)\nif err != nil {\n httperror.WriteError(w, http.StatusForbidden,\n \"permission denied to access the environment\", err)\n // missing return \u2014 tokenData is nil, execution continues\n}\n\n// tokenData.ID dereferenced on the next line:\n_, ok := handler.KubernetesClientFactory.GetProxyKubeClient(\n strconv.Itoa(endpointID), strconv.Itoa(int(tokenData.ID)))\n```\nThe fix adds a single return after the WriteError call in both CE and EE:\n\n```go\n// post-fix\nif err != nil {\n httperror.WriteError(w, http.StatusForbidden,\n \"permission denied to access the environment\", err)\n return\n}\n```\n\n## Impact\n- Kubernetes authorization bypass. A low-privileged Portainer user can reach Kubernetes API endpoints on environments their role does not permit, with the proxy client of the legitimate session used as the vehicle.\n- Cluster resource access. Depending on the service account permissions Portainer holds on the cluster, the attacker can read or modify namespaced resources \u2014 including pods, secrets, config maps, and deployments.\n- Potential for lateral movement. Kubernetes secrets readable through this path may contain credentials for other services within the cluster or the broader infrastructure.\n\n## Timeline\n- 2026-02-16: Fix merged to develop.\n- 2026-02-25: 2.39.0 released with fix.\n- 2026-05-07: 2.33.8 released with backport fix.",
"id": "GHSA-mgq6-4x29-88r3",
"modified": "2026-06-09T10:25:25Z",
"published": "2026-05-14T16:24:29Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/portainer/portainer/security/advisories/GHSA-mgq6-4x29-88r3"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-44882"
},
{
"type": "PACKAGE",
"url": "https://github.com/portainer/portainer"
},
{
"type": "WEB",
"url": "https://github.com/portainer/portainer/releases/tag/2.33.8"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "Portainer\u0027s Kubernetes middleware continues after token validation failure, bypassing endpoint authorization"
}
GHSA-MH3W-PWXW-972F
Vulnerability from github – Published: 2025-10-07 21:31 – Updated: 2025-10-07 21:31Nagios Log Server before 2024R1.3.2 allows authenticated users (with read-only API access) to stop the Elasticsearch service via a /nagioslogserver/index.php/api/system/stop?subsystem=elasticsearch call. The service stops even though "message": "Could not stop elasticsearch" is in the API response. This is GL:NLS#474.
{
"affected": [],
"aliases": [
"CVE-2025-44824"
],
"database_specific": {
"cwe_ids": [
"CWE-863"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-10-07T20:15:35Z",
"severity": "HIGH"
},
"details": "Nagios Log Server before 2024R1.3.2 allows authenticated users (with read-only API access) to stop the Elasticsearch service via a /nagioslogserver/index.php/api/system/stop?subsystem=elasticsearch call. The service stops even though \"message\": \"Could not stop elasticsearch\" is in the API response. This is GL:NLS#474.",
"id": "GHSA-mh3w-pwxw-972f",
"modified": "2025-10-07T21:31:07Z",
"published": "2025-10-07T21:31:07Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-44824"
},
{
"type": "WEB",
"url": "https://github.com/skraft9/nagios-log-server-dos"
},
{
"type": "WEB",
"url": "https://www.nagios.com/changelog/#log-server"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:L/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-MHC8-P3JX-84MM
Vulnerability from github – Published: 2026-05-06 19:50 – Updated: 2026-05-13 16:31Summary
The reset_user_password and gym_permissions_user_edit views in wger perform a gym-scope authorization check using Python object comparison (!=) that evaluates None != None as False, silently bypassing the guard when both the attacker and victim have no gym assignment (gym=None). A user with gym.manage_gym permission and gym=None can reset the password of any other gym=None user; the new plaintext password is returned verbatim in the HTML response body, enabling one-shot full account takeover. The victim's original password is invalidated, locking them out permanently.
Details
File: wger/gym/views/user.py
The authorization guard in reset_user_password (and the parallel check in gym_permissions_user_edit) uses Django ORM object comparison:
# VULNERABLE - wger/gym/views/user.py
if request.user.userprofile.gym != user.userprofile.gym:
return HttpResponseForbidden()
When both request.user.userprofile.gym and user.userprofile.gym are None (representing users with no gym assignment - the default for newly registered users before gym linking), Python evaluates None != None as False. The guard therefore passes without raising HttpResponseForbidden, and execution continues unconditionally to:
password = password_generator()
user.set_password(password)
user.save()
return render(request, 'user/trainer_login.html', {'password': password, ...})
The generated password is rendered verbatim in the response body.
Affected endpoints:
- GET /en/gym/user/<user_pk>/reset-user-password -> wger.gym.views.user.reset_user_password
- GET /en/gym/user/<user_pk>/edit -> wger.gym.views.user.gym_permissions_user_edit
Suggested patch:
--- a/wger/gym/views/user.py
+++ b/wger/gym/views/user.py
- if request.user.userprofile.gym != user.userprofile.gym:
- return HttpResponseForbidden()
+ trainer_gym_id = request.user.userprofile.gym_id # raw FK int
+ member_gym_id = user.userprofile.gym_id
+
+ if trainer_gym_id is None or trainer_gym_id != member_gym_id:
+ return HttpResponseForbidden()
The _id suffix accesses the raw integer foreign key, bypassing Python's object identity semantics. The explicit is None guard rejects unaffiliated trainers immediately, regardless of the victim's gym status. Apply the same same_gym() helper pattern to all five views sharing this check: reset_user_password, gym_permissions_user_edit, admin_notes_list, documents_list, contracts_list.
PoC
Tested on wger/server:latest Docker image (runtime: Django 5.2.13). Two test users: trainer1 (gym.manage_gym permission, userprofile.gym=None) and alice (regular user, userprofile.gym=None).
Step 1 - Authenticate as trainer with manage_gym permission and gym=None:
POST /en/user/login HTTP/1.1
Host: target
Content-Type: application/x-www-form-urlencoded
username=trainer1&password=[REDACTED]&csrfmiddlewaretoken=[REDACTED]
-> 302 Found; Set-Cookie: sessionid=[trainer1_session]
Step 2 - Trigger cross-tenant password reset:
GET /en/gym/user/2/reset-user-password HTTP/1.1
Host: target
Cookie: sessionid=[trainer1_session]
-> 200 OK
<tr><th>Password</th><td>[GENERATED_PLAINTEXT_PASSWORD]</td></tr>
Step 3 - Authenticate as victim (alice) using leaked password:
POST /en/user/login HTTP/1.1
Host: target
username=alice&password=[GENERATED_PLAINTEXT_PASSWORD]&csrfmiddlewaretoken=[...]
-> 302 Found; authenticated as alice
(alice's ORIGINAL password is now invalid - permanent lockout)
RBAC Disproof Protocol (three-scenario test):
- Scenario A (admin, same-gym) -> HTTP 200 (expected - documented feature)
- Scenario B (trainer1 gym=None -> alice gym=None) -> HTTP 200 with plaintext password in body (expected HTTP 403)
- Scenario C (trainer1 gym=1 -> alice gym=2) -> HTTP 403 (expected - guard works when gyms differ, confirms bypass is None-specific)
Reproducibility: 2/2 runs after clean-baseline database reset.
Impact
An attacker with gym.manage_gym permission and gym=None can:
- Reset the password of any other
gym=Noneuser on the wger instance. - Receive the new plaintext password in the HTTP response body.
- Log in as the victim immediately.
- Permanently lock the victim out (original password invalidated).
Affected deployments: every wger instance where gym.manage_gym permission is delegated to non-admin users AND any other users exist with gym=None. The gym=None state is the default for newly registered users before manual gym assignment, so every public-registration wger instance is affected.
Severity: Critical (CVSS 9.9). Network-reachable, low complexity, requires only low privilege (delegated trainer), scope change (impersonation of other tenant), complete confidentiality/integrity/availability loss for all unaffiliated accounts.
This is the same structural bug class as the sibling finding affecting trainer_login (submitted separately). The root cause - Django ORM object-!= returning False when both sides are None - appears across five views and warrants a shared same_gym() helper.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 2.5"
},
"package": {
"ecosystem": "PyPI",
"name": "wger"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.6"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-43948"
],
"database_specific": {
"cwe_ids": [
"CWE-863"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-06T19:50:31Z",
"nvd_published_at": "2026-05-12T22:16:35Z",
"severity": "CRITICAL"
},
"details": "### Summary\n\nThe `reset_user_password` and `gym_permissions_user_edit` views in wger perform a gym-scope authorization check using Python object comparison (`!=`) that evaluates `None != None` as `False`, silently bypassing the guard when both the attacker and victim have no gym assignment (`gym=None`). A user with `gym.manage_gym` permission and `gym=None` can reset the password of **any other `gym=None` user**; the new plaintext password is returned verbatim in the HTML response body, enabling one-shot full account takeover. The victim\u0027s original password is invalidated, locking them out permanently.\n\n### Details\n\n**File**: `wger/gym/views/user.py`\n\nThe authorization guard in `reset_user_password` (and the parallel check in `gym_permissions_user_edit`) uses Django ORM object comparison:\n\n```python\n# VULNERABLE - wger/gym/views/user.py\nif request.user.userprofile.gym != user.userprofile.gym:\n return HttpResponseForbidden()\n```\n\nWhen both `request.user.userprofile.gym` and `user.userprofile.gym` are `None` (representing users with no gym assignment - the default for newly registered users before gym linking), Python evaluates `None != None` as `False`. The guard therefore passes without raising `HttpResponseForbidden`, and execution continues unconditionally to:\n\n```python\npassword = password_generator()\nuser.set_password(password)\nuser.save()\nreturn render(request, \u0027user/trainer_login.html\u0027, {\u0027password\u0027: password, ...})\n```\n\nThe generated password is rendered verbatim in the response body.\n\n**Affected endpoints**:\n- `GET /en/gym/user/\u003cuser_pk\u003e/reset-user-password` -\u003e `wger.gym.views.user.reset_user_password`\n- `GET /en/gym/user/\u003cuser_pk\u003e/edit` -\u003e `wger.gym.views.user.gym_permissions_user_edit`\n\n**Suggested patch**:\n\n```diff\n--- a/wger/gym/views/user.py\n+++ b/wger/gym/views/user.py\n- if request.user.userprofile.gym != user.userprofile.gym:\n- return HttpResponseForbidden()\n+ trainer_gym_id = request.user.userprofile.gym_id # raw FK int\n+ member_gym_id = user.userprofile.gym_id\n+\n+ if trainer_gym_id is None or trainer_gym_id != member_gym_id:\n+ return HttpResponseForbidden()\n```\n\nThe `_id` suffix accesses the raw integer foreign key, bypassing Python\u0027s object identity semantics. The explicit `is None` guard rejects unaffiliated trainers immediately, regardless of the victim\u0027s gym status. Apply the same `same_gym()` helper pattern to all five views sharing this check: `reset_user_password`, `gym_permissions_user_edit`, `admin_notes_list`, `documents_list`, `contracts_list`.\n\n### PoC\n\nTested on `wger/server:latest` Docker image (runtime: Django 5.2.13). Two test users: `trainer1` (`gym.manage_gym` permission, `userprofile.gym=None`) and `alice` (regular user, `userprofile.gym=None`).\n\n**Step 1** - Authenticate as trainer with `manage_gym` permission and `gym=None`:\n\n```\nPOST /en/user/login HTTP/1.1\nHost: target\nContent-Type: application/x-www-form-urlencoded\n\nusername=trainer1\u0026password=[REDACTED]\u0026csrfmiddlewaretoken=[REDACTED]\n\n-\u003e 302 Found; Set-Cookie: sessionid=[trainer1_session]\n```\n\n**Step 2** - Trigger cross-tenant password reset:\n\n```\nGET /en/gym/user/2/reset-user-password HTTP/1.1\nHost: target\nCookie: sessionid=[trainer1_session]\n\n-\u003e 200 OK\n\u003ctr\u003e\u003cth\u003ePassword\u003c/th\u003e\u003ctd\u003e[GENERATED_PLAINTEXT_PASSWORD]\u003c/td\u003e\u003c/tr\u003e\n```\n\n**Step 3** - Authenticate as victim (alice) using leaked password:\n\n```\nPOST /en/user/login HTTP/1.1\nHost: target\n\nusername=alice\u0026password=[GENERATED_PLAINTEXT_PASSWORD]\u0026csrfmiddlewaretoken=[...]\n\n-\u003e 302 Found; authenticated as alice\n(alice\u0027s ORIGINAL password is now invalid - permanent lockout)\n```\n\n**RBAC Disproof Protocol** (three-scenario test):\n- Scenario A (admin, same-gym) -\u003e HTTP 200 (expected - documented feature)\n- Scenario B (trainer1 gym=None -\u003e alice gym=None) -\u003e **HTTP 200 with plaintext password in body** (expected HTTP 403)\n- Scenario C (trainer1 gym=1 -\u003e alice gym=2) -\u003e HTTP 403 (expected - guard works when gyms differ, confirms bypass is `None`-specific)\n\nReproducibility: 2/2 runs after clean-baseline database reset.\n\n### Impact\n\nAn attacker with `gym.manage_gym` permission and `gym=None` can:\n\n1. Reset the password of any other `gym=None` user on the wger instance.\n2. Receive the new plaintext password in the HTTP response body.\n3. Log in as the victim immediately.\n4. Permanently lock the victim out (original password invalidated).\n\n**Affected deployments**: every wger instance where `gym.manage_gym` permission is delegated to non-admin users AND any other users exist with `gym=None`. The `gym=None` state is the **default for newly registered users** before manual gym assignment, so every public-registration wger instance is affected.\n\n**Severity**: Critical (CVSS 9.9). Network-reachable, low complexity, requires only low privilege (delegated trainer), scope change (impersonation of other tenant), complete confidentiality/integrity/availability loss for all unaffiliated accounts.\n\nThis is the same structural bug class as the sibling finding affecting `trainer_login` (submitted separately). The root cause - Django ORM object-`!=` returning `False` when both sides are `None` - appears across five views and warrants a shared `same_gym()` helper.",
"id": "GHSA-mhc8-p3jx-84mm",
"modified": "2026-05-13T16:31:51Z",
"published": "2026-05-06T19:50:31Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/wger-project/wger/security/advisories/GHSA-mhc8-p3jx-84mm"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-43948"
},
{
"type": "PACKAGE",
"url": "https://github.com/wger-project/wger"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "wger: cross-tenant password reset and plaintext disclosure via gym=None bypass"
}
Mitigation
- Divide the product into anonymous, normal, privileged, and administrative areas. Reduce the attack surface by carefully mapping roles with data and functionality. Use role-based access control (RBAC) [REF-229] to enforce the roles at the appropriate boundaries.
- Note that this approach may not protect against horizontal authorization, i.e., it will not protect a user from attacking others with the same role.
Mitigation
Ensure that access control checks are performed related to the business logic. These checks may be different than the access control checks that are applied to more generic resources such as files, connections, processes, memory, and database records. For example, a database may restrict access for medical records to a specific database user, but each record might only be intended to be accessible to the patient and the patient's doctor [REF-7].
Mitigation MIT-4.4
Strategy: Libraries or Frameworks
- Use a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid.
- For example, consider using authorization frameworks such as the JAAS Authorization Framework [REF-233] and the OWASP ESAPI Access Control feature [REF-45].
Mitigation
- For web applications, make sure that the access control mechanism is enforced correctly at the server side on every page. Users should not be able to access any unauthorized functionality or information by simply requesting direct access to that page.
- One way to do this is to ensure that all pages containing sensitive information are not cached, and that all such pages restrict access to requests that are accompanied by an active and authenticated session token associated with a user who has the required permissions to access that page.
Mitigation
Use the access control capabilities of your operating system and server environment and define your access control lists accordingly. Use a "default deny" policy when defining these ACLs.
No CAPEC attack patterns related to this CWE.