Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessAuthenticate as gym_trainer in target gym
-
ExploitGET /user/<manager_id>/deactivate
-
ExecutionOR-logic mixin grants access, no hierarchy check
-
ImpactHigher-privileged manager account set inactive, locked out
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A06:2025 - Insecure Design
ASVS 5.0
V8 - Authorization Least privilege enforcement
MITRE ATT&CK
1 technique across 1 tactic: Privilege Escalation The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up. |
| Exploitation Conditions | Requires an authenticated user who holds the gym.gym_trainer permission (or gym.manage_gym / gym.manage_gyms) AND belongs to the SAME gym as the victim - the dispatch() method enforces same-gym membership and returns HttpResponseForbidden for cross-gym targets, so the attack cannot cross gym boundaries. No non-default configuration, feature flag, or user interaction is needed; the deactivate/activate endpoints behave this way by default. The limiting factors defenders should weigh: the attacker must already possess a trainer-or-higher account in the victim's gym (so this is an insider/lower-privileged-role escalation, not remote-unauthenticated), and the amplifying factor is that get_permission_list() always lets a gym manager create trainer accounts, so a manager-provisioned trainer can turn around and disable that manager. Affected: wger prior to 2.6. |
| Impact | This is a genuine but bounded-risk privilege-escalation flaw (CWE-269), not a high-CVSS-but-hollow finding, yet also not an internet-wide emergency. The input CVSS of 7.1 (High) rests on CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:H/A:N: network-reachable, low attack complexity, and only low-privilege authentication (a gym_trainer account) with no user interaction, which makes exploitation trivially reliable for anyone who already holds a trainer role. Countervailing signals keep real-world risk moderate: no EPSS score was provided, the CVE is NOT on CISA KEV ('no public exploit identified' does not apply - a PoC IS published), and the product's deployment footprint is low (niche self-hosted open-source fitness manager). The threat model is therefore insider/lower-tier-operator abuse within a shared gym, not mass remote exploitation. One metric tension to verify: the input assigns C:L, but account deactivation discloses no data - this analysis assesses C:N and treats the true impact as integrity (unauthorized modification of account state), so the 7.1 may slightly overweight confidentiality. Bottom line: prioritize patching for any multi-tenant/multi-role wger deployment, but the limited product prevalence and required trainer-level access cap the blast radius. |
| Exploit ScenarioDerived | An attacker holding only the gym_trainer role (which a gym manager can themselves create, enabling a created-trainer-turns-on-creator scenario) sends a single GET request to /en/user/<manager_user_id>/deactivate for a gym_manager or general_gym_manager in the same gym, immediately setting is_active=False and locking that higher-privileged user out. A working proof-of-concept and attack steps are published in the GHSA advisory. The CVSS AV:N/AC:L/PR:L/UI:N profile means the attack is a low-complexity, no-interaction web request requiring only low-privilege authentication. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Oct 07, 2026
Account-deactivation privilege escalation in wger before 2.6 lets an authenticated user who holds only the gym_trainer role disable higher-privileged accounts - including gym_manager and general_gym_manager - within the same gym, locking those users out of the application entirely. Access control on UserDeactivateView (and the mirror-image UserActivateView) uses OR logic across gym.manage_gym, gym.manage_gyms and gym.gym_trainer, with no privilege-hierarchy check and only a same-gym membership check in dispatch(), so the assessed vector is CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N - an insider/lower-privileged-role escalation, not a remote unauthenticated attack, and one that cannot cross gym boundaries. Publicly available exploit code exists (the vendor advisory itself publishes a working PoC of the GET request), but there is no confirmed active exploitation (CISA KEV) and no EPSS score was supplied in the intelligence feed; a gym manager provisioning a trainer account, which get_permission_list() always allows, is the amplifying path by which a trainer can then turn around and disable the manager who created it.
RemediationAI
Upgrade to wger 2.6, the version the vendor advisory and release notes identify as containing the fix (https://github.com/wger-project/wger/releases/tag/2.6, release notes also at https://github.com/wger-project/wger/security/advisories/GHSA-x249-cx55-2h87); there is no vendor-released patch identified for earlier branches, so upgrading is the only complete fix and the package-feed entry recording no fixed pip version should be treated as stale rather than as evidence that 2.6 is unaffected. Plan for breaking changes in 2.6 that affect the upgrade itself: mobile offline-mode backend changes, newly supported social login and two-factor/passkey authentication (users must re-login on the website after the upgrade), a new efficient /api/v2/ingredient-sync endpoint plus nutrition-score range filters on the ingredient API, and JWT refresh tokens that now rotate on every use with blacklist-after-rotation - the release guidance recommends setting REFRESH_TOKEN_LIFETIME to roughly 3000 in prod.env, and shortening it improperly will silently break API clients that do not persist rotated refresh tokens. If an immediate upgrade is not feasible, the actionable compensating controls are: remove 'trainer' from the roles returned by get_permission_list() in wger/gym/helpers.py and restrict trainer creation to a trusted administrator, accepting that this disables the normal self-service trainer provisioning workflow; or backport the missing privilege-hierarchy check into UserDeactivateView.dispatch() and UserActivateView so that a requester may only act on targets of equal or lower rank, accepting the maintenance burden of re-applying a local patch on every release. Additionally, audit and reverse unauthorized account deactivations (an administrator can flip is_active back to True, since this flaw manipulates account state rather than destroying data), add monitoring or alerting on the /user/<pk>/deactivate and /activate endpoints, and avoid exposing those endpoints broadly while the mitigating patch is in place - note that a reverse-proxy restriction on those paths is not a clean control here because legitimate gym managers need the same URLs, so it should be used only to constrain untrusted networks, not as a role-level substitute for the fix.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 1 package in pypi
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
wger is a self-hosted Django fitness/workout manager distributed both as source and as a pip package, and its gym module layers role-based permissions on top of Django's permission framework. The root cause class is CWE-269 (Improper Privilege Management): UserDeactivateView in wger/core/views/user.py (line 378) declares permission_required = ('gym.manage_gym', 'gym.manage_gyms', 'gym.gym_trainer'), and the project's own WgerMultiplePermissionRequiredMixin in wger/utils/generic_views.py (line 48) implements has_permission() as a loop that returns True as soon as ANY one of those permissions is present - effectively an OR check rather than the AND semantics an administrator might assume. The view's dispatch() only verifies that requester and target share the same gym_id and returns HttpResponseForbidden for cross-gym targets; it never compares relative privilege, so a requester holding the lowest of the three permissions can act on a target holding a higher one. UserActivateView (line 415) carries the identical defect, meaning deactivated accounts can also be reactivated by an under-privileged actor. A contributing design factor is get_permission_list() in wger/gym/helpers.py (line 102), which always includes 'trainer' among the assignable roles, so any gym manager can mint trainer accounts whose holders can subsequently deactivate that manager. Because the CPE is a bare wger-project:wger entry with a wildcard version, every release prior to the 2.6 fix is in scope for this check; the underlying technology is a standard Django request/view/permission flow, so exploitation is a single authenticated HTTP GET with no user interaction on the victim's side.
Know when Wger 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
AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:H/A:N
Web-reachable (AV:N), trivial request (AC:L), requires a low-privilege trainer account (PR:L), no UI; impact is unauthorized account-state modification (I:H), no data disclosure (C:N).
Primary rating from Vendor (GitHub_M).
CVSS VectorVendor: GitHub_M
Lifecycle Timeline
2DescriptionCVE.org
wger is a free, open-source workout and fitness manager. Prior to version 2.6, a user with only the gym_trainer permission can deactivate any account in the same gym, including gym_manager and general_gym_manager accounts. The UserDeactivateView grants access to anyone holding any one of gym.manage_gym, gym.manage_gyms, or gym.gym_trainer (OR logic via WgerMultiplePermissionRequiredMixin), and performs no privilege-hierarchy check to prevent a lower-privileged role from disabling a higher-privileged one. Version 2.6 fixes the issue.
Technical POC Analysis
CWE-269 (Improper Privilege Management): the deactivation view authenticates the permission to act but never compares the relative rank of actor and target, so any holder of the lowest gym role can d…
Full technical POC analysis - root cause, step-by-step exploitation and patch breakdown - is part of the Pro and Business plans.
Executive ViewAI
wger deployments before 2.6 expose a high-severity account-deactivation privilege escalation in which an authenticated gym_trainer can lock out gym_manager and general_gym_manager accounts within the same gym, disrupting local gym administration and user access. The issue is limited to same-gym boundaries and requires an authenticated low-privileged insider, but publicly available exploit code exists and no vendor-released patch identified at time of analysis. Leadership should prioritize visibility into trainer-role assignments and account-deactivation events because a single malicious or careless trainer account could disable operational managers.
No vendor-released patch identified at time of analysis. Interim mitigations include enforcing least privilege by limiting gym_trainer role assignments, auditing and removing unnecessary trainer accounts, monitoring account-deactivation events for same-gym gym_manager and general_gym_manager targets, restricting access to UserDeactivateView and UserActivateView to manager roles where operationally feasible, and applying a code-level privilege-hierarchy check until a vendor fix is available.
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
Privilege escalation occurs when an attacker leverages flaws in access control mechanisms to gain permissions beyond what they were originally granted.
Improper Restriction of Excessive Authentication Attempts in GitHub repository wger-project/wger prior to 2.2. Rated cri
Cross Site Scripting vulnerability in wger Project wger Workout Manager v.2.2.0a3 allows a remote attacker to gain privi
Cross Site Request Forgery (CSRF) vulnerability in wger Project wger Workout Manager 2.2.0a3 allows a remote attacker to
Wger versions up to 2.4 allow authenticated users to access other users' private nutrition plans through insecure direct
Wger versions up to 2.4 expose all users' repetition configuration data to any authenticated attacker due to missing aut
Uncontrolled resource consumption in wger before 2.5 allows any authenticated user to exhaust server worker threads and
wger is a free, open-source workout and fitness manager. Five routine detail action endpoints check a cache before calli
Cross-user integrity corruption in wger versions prior to 2.6 allows authenticated attackers to inject arbitrary workout
Incomplete authorization fix in wger through master exposes three user-management views in wger/core/views/user.py to th
wger before 2.6 contains a CSRF bypass (CWE-352) that lets an attacker-controlled web page silently rebind an authentica
Cross-site request forgery in wger's gym password-reset endpoint allows a remote attacker to force an arbitrary member's
Open redirect in wger's trainer_login view allows an attacker to redirect an authenticated trainer's browser to an arbit
EUVD-2026-94333
GHSA-x249-cx55-2h87
NVD
CVE.org
EPSS
Vulnrichment
Exploit-DB