{"id":"CVE-2026-86256","aliases":["EUVD-2026-72112","GHSA-rc6j-63fm-mhq4","GHSA-vqv8-j3mj-wjxj"],"status":"published","title":"wger before 2.6 Open Redirect via trainer-login next parameter","description":"wger before 2.6 (affected versions \u003c= 2.5.0) contains an open redirect vulnerability in the trainer_login view (wger/core/views/user.py). After a trainer enters impersonation mode, the view redirects to the user-supplied 'next' GET parameter via HttpResponseRedirect() without validating it with url_has_allowed_host_and_scheme(). An attacker who delivers a crafted link to an authenticated trainer can redirect the trainer's browser to an attacker-controlled domain, enabling phishing and leaking the wger URL structure (including the impersonated user's user_pk) via the Referer header.","severity":{"version":"4.0","score":5.1,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:L/VI:L/VA:N/SC:L/SI:L/SA:N","level":"medium","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-11","score":0.00234,"percentile":0.14456,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-601"],"published":"2026-05-06T19:50:52Z","modified":"2026-10-28T02:30:35Z","fixes":[{"ecosystem":"PyPI","package":"wger","fixed_in":["2.6"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"PyPI","package":"wger","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"2.5"},{"fixed":"2.6"}]}]},{"source":"osv","ecosystem":"PyPI","package":"wger","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.6"}]}],"versions":["1.1","1.1.1","1.2","1.2rc1","1.3","1.4","1.5","1.6","1.6.1","1.7","1.8","1.9","2.0","2.1"]}],"products":[{"vendor":"wger-project","product":"wger"}],"references":[{"url":"https://github.com/wger-project/wger/security/advisories/GHSA-vqv8-j3mj-wjxj","tags":["vendor-advisory","exploit","advisory","web"]},{"url":"https://www.vulncheck.com/advisories/wger-before-2.6-open-redirect-via-trainer-login-next-parameter","tags":["third-party-advisory","advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-86256","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-rc6j-63fm-mhq4"},{"url":"https://github.com/advisories/GHSA-vqv8-j3mj-wjxj"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/86xxx/CVE-2026-86256.json","tags":["advisory"]},{"url":"https://github.com/wger-project/wger","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-86256","title":"wger before 2.6 Open Redirect via trainer-login next parameter","description":"wger before 2.6 (affected versions \u003c= 2.5.0) contains an open redirect vulnerability in the trainer_login view (wger/core/views/user.py). After a trainer enters impersonation mode, the view redirects to the user-supplied 'next' GET parameter via HttpResponseRedirect() without validating it with url_has_allowed_host_and_scheme(). An attacker who delivers a crafted link to an authenticated trainer can redirect the trainer's browser to an attacker-controlled domain, enabling phishing and leaking the wger URL structure (including the impersonated user's user_pk) via the Referer header.","status":"published","published":"2026-09-06T12:00:30.256Z","modified":"2026-09-09T13:59:36.446Z","cvss":[{"version":"4.0","score":5.1,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:L/VI:L/VA:N/SC:L/SI:L/SA:N","level":"medium","assessor":"cna"},{"version":"3.1","score":5.4,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N","level":"medium","assessor":"cna"}],"cwes":["CWE-601"],"updated_at":"2026-11-02T13:49:42.666099Z"}],"euvd":[{"id":"EUVD-2026-72112","description":"wger before 2.6 (affected versions \u003c= 2.5.0) contains an open redirect vulnerability in the trainer_login view (wger/core/views/user.py). After a trainer enters impersonation mode, the view redirects to the user-supplied 'next' GET parameter via HttpResponseRedirect() without validating it with url_has_allowed_host_and_scheme(). An attacker who delivers a crafted link to an authenticated trainer can redirect the trainer's browser to an attacker-controlled domain, enabling phishing and leaking the wger URL structure (including the impersonated user's user_pk) via the Referer header.","status":"published","published":"2026-09-06T12:00:30Z","modified":"2026-09-09T13:59:36Z","cvss":[{"version":"4.0","score":5.1,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:L/VI:L/VA:N/SC:L/SI:L/SA:N","level":"medium"}],"updated_at":"2026-11-02T17:28:27.325238Z"}],"ghsa":[{"id":"GHSA-rc6j-63fm-mhq4","title":"wger before 2.6 (affected versions \u003c= 2.5.0) contains an open redirect vulnerability in the...","description":"wger before 2.6 (affected versions \u003c= 2.5.0) contains an open redirect vulnerability in the trainer_login view (wger/core/views/user.py). After a trainer enters impersonation mode, the view redirects to the user-supplied 'next' GET parameter via HttpResponseRedirect() without validating it with url_has_allowed_host_and_scheme(). An attacker who delivers a crafted link to an authenticated trainer can redirect the trainer's browser to an attacker-controlled domain, enabling phishing and leaking the wger URL structure (including the impersonated user's user_pk) via the Referer header.","status":"published","published":"2026-09-06T12:30:24Z","modified":"2026-09-06T12:30:30Z","cvss":[{"version":"4.0","score":5.1,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:L/VI:L/VA:N/SC:L/SI:L/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","level":"medium"},{"version":"3.1","score":5.4,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N","level":"medium"}],"cwes":["CWE-601"],"updated_at":"2026-11-02T15:11:25.773648Z"},{"id":"GHSA-vqv8-j3mj-wjxj","title":"wger: trainer_login open redirect - ?next= parameter not validated against host","description":"### Summary\n\nThe `trainer_login` view in wger redirects to `request.GET['next']` directly via `HttpResponseRedirect()` without calling `url_has_allowed_host_and_scheme()`. After the trainer successfully enters impersonation mode, their browser is redirected to any attacker-controlled URL supplied in the `?next=` parameter, enabling Referer exfiltration and phishing.\n\n### Details\n\n**File**: `wger/core/views/user.py`, approximately line 203\n\n```python\n# VULNERABLE - wger/core/views/user.py\nif not own:\n    request.session['trainer.identity'] = orig_user_pk\n    if request.GET.get('next'):\n        return HttpResponseRedirect(request.GET['next'])   # no host/scheme validation\n```\n\nAfter the impersonation logic succeeds, the view performs no validation of the `next` parameter before issuing the redirect. An attacker who can deliver a crafted link (e.g. `/en/user/2/trainer-login?next=https://evil.example/steal`) to a trainer can redirect the trainer's browser to any external host immediately after the impersonation session is established. The `Location` header contains the raw attacker-controlled URL.\n\n**Affected endpoint**:\n- `GET /en/user/\u003cuser_pk\u003e/trainer-login` -\u003e `wger.core.views.user.trainer_login` (the `?next=` redirect branch)\n\n**Suggested patch**:\n\n```diff\n--- a/wger/core/views/user.py\n+++ b/wger/core/views/user.py\n+from django.utils.http import url_has_allowed_host_and_scheme\n+\n if not own:\n     request.session['trainer.identity'] = orig_user_pk\n-    if request.GET.get('next'):\n-        return HttpResponseRedirect(request.GET['next'])\n+    next_url = request.GET.get('next')\n+    if next_url and url_has_allowed_host_and_scheme(\n+        next_url, allowed_hosts={request.get_host()}, require_https=request.is_secure()\n+    ):\n+        return HttpResponseRedirect(next_url)\n     return HttpResponseRedirect(reverse('core:index'))\n```\n\nAdding `@require_POST` to `trainer_login` (see also VULN-030) moves the `next` parameter to the POST body where CSRF protection applies and eliminates the combined CSRF + open-redirect attack surface entirely.\n\n### PoC\n\nTested on `wger/server:latest` Docker image. Victim: `trainer1` (`gym.gym_trainer` permission).\n\nStep 1 - Authenticate as trainer:\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\nStep 2 - Trainer clicks (or is delivered) the crafted link:\n\n```\nGET /en/user/2/trainer-login?next=https://evil.example/steal HTTP/1.1\nHost: target\nCookie: sessionid=[trainer1_session]\n\n-\u003e 302 Found\n   Location: https://evil.example/steal\n```\n\nStep 3 - Attacker server logs Referer:\n\n```\nReferer: http://target/en/user/2/trainer-login?next=https://evil.example/steal\n(victim user_pk and next URL exposed)\n```\n\nReproducibility: 2/2 runs.\n\n### Impact\n\nAn attacker who can deliver a crafted URL to a trainer (phishing email, malicious gym management system integration, social engineering) can redirect the trainer's browser to an attacker-controlled domain after the trainer enters impersonation mode. The redirect leaks:\n\n- The wger URL structure (including the impersonated user's `user_pk`) via the browser `Referer` header.\n- The session-rebound cookie (if the attacker page subsequently triggers an authenticated request with `credentials: 'include'` targeting wger, any same-site cookie without SameSite=Strict is attached).\n\nCombined with the trainer-login scope bypass (submitted separately), this primitive allows an attacker to silently impersonate arbitrary `gym=None` users and then land the trainer on an attacker page for credential harvesting.\n\n**Affected deployments**: every wger instance where `gym.gym_trainer` is delegated to non-admin users.\n\n**Severity**: Medium (CVSS 5.4). Network-reachable, low complexity, low privilege (trainer role), requires victim interaction (click), scope change (attacker's origin).","status":"published","published":"2026-05-06T19:50:52Z","modified":"2026-05-06T19:50:57Z","cvss":[{"version":"3.1","score":5.4,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N","level":"medium"}],"cwes":["CWE-601"],"updated_at":"2026-11-02T14:40:02.883746Z"}],"nvd":[{"id":"CVE-2026-86256","description":"wger before 2.6 (affected versions \u003c= 2.5.0) contains an open redirect vulnerability in the trainer_login view (wger/core/views/user.py). After a trainer enters impersonation mode, the view redirects to the user-supplied 'next' GET parameter via HttpResponseRedirect() without validating it with url_has_allowed_host_and_scheme(). An attacker who delivers a crafted link to an authenticated trainer can redirect the trainer's browser to an attacker-controlled domain, enabling phishing and leaking the wger URL structure (including the impersonated user's user_pk) via the Referer header.","status":"published","published":"2026-09-06T12:17:16.567Z","modified":"2026-09-09T14:17:22.1Z","cvss":[{"version":"4.0","score":5.1,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:L/VI:L/VA:N/SC:L/SI:L/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","level":"medium","assessor":"secondary"},{"version":"3.1","score":5.4,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N","level":"medium","assessor":"secondary"}],"cwes":["CWE-601"],"updated_at":"2026-11-02T14:12:44.082631Z"}],"osv":[{"id":"CVE-2026-86256","title":"wger before 2.6 Open Redirect via trainer-login next parameter","description":"wger before 2.6 (affected versions \u003c= 2.5.0) contains an open redirect vulnerability in the trainer_login view (wger/core/views/user.py). After a trainer enters impersonation mode, the view redirects to the user-supplied 'next' GET parameter via HttpResponseRedirect() without validating it with url_has_allowed_host_and_scheme(). An attacker who delivers a crafted link to an authenticated trainer can redirect the trainer's browser to an attacker-controlled domain, enabling phishing and leaking the wger URL structure (including the impersonated user's user_pk) via the Referer header.","status":"published","published":"2026-09-06T12:00:30.256Z","modified":"2026-10-28T02:30:35.171344062Z","cvss":[{"version":"4.0","score":5.1,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:L/VI:L/VA:N/SC:L/SI:L/SA:N","level":"medium"}],"cwes":["CWE-601"],"updated_at":"2026-11-02T15:45:18.825071Z"},{"id":"GHSA-vqv8-j3mj-wjxj","title":"wger: trainer_login open redirect - ?next= parameter not validated against host","description":"### Summary\n\nThe `trainer_login` view in wger redirects to `request.GET['next']` directly via `HttpResponseRedirect()` without calling `url_has_allowed_host_and_scheme()`. After the trainer successfully enters impersonation mode, their browser is redirected to any attacker-controlled URL supplied in the `?next=` parameter, enabling Referer exfiltration and phishing.\n\n### Details\n\n**File**: `wger/core/views/user.py`, approximately line 203\n\n```python\n# VULNERABLE - wger/core/views/user.py\nif not own:\n    request.session['trainer.identity'] = orig_user_pk\n    if request.GET.get('next'):\n        return HttpResponseRedirect(request.GET['next'])   # no host/scheme validation\n```\n\nAfter the impersonation logic succeeds, the view performs no validation of the `next` parameter before issuing the redirect. An attacker who can deliver a crafted link (e.g. `/en/user/2/trainer-login?next=https://evil.example/steal`) to a trainer can redirect the trainer's browser to any external host immediately after the impersonation session is established. The `Location` header contains the raw attacker-controlled URL.\n\n**Affected endpoint**:\n- `GET /en/user/\u003cuser_pk\u003e/trainer-login` -\u003e `wger.core.views.user.trainer_login` (the `?next=` redirect branch)\n\n**Suggested patch**:\n\n```diff\n--- a/wger/core/views/user.py\n+++ b/wger/core/views/user.py\n+from django.utils.http import url_has_allowed_host_and_scheme\n+\n if not own:\n     request.session['trainer.identity'] = orig_user_pk\n-    if request.GET.get('next'):\n-        return HttpResponseRedirect(request.GET['next'])\n+    next_url = request.GET.get('next')\n+    if next_url and url_has_allowed_host_and_scheme(\n+        next_url, allowed_hosts={request.get_host()}, require_https=request.is_secure()\n+    ):\n+        return HttpResponseRedirect(next_url)\n     return HttpResponseRedirect(reverse('core:index'))\n```\n\nAdding `@require_POST` to `trainer_login` (see also VULN-030) moves the `next` parameter to the POST body where CSRF protection applies and eliminates the combined CSRF + open-redirect attack surface entirely.\n\n### PoC\n\nTested on `wger/server:latest` Docker image. Victim: `trainer1` (`gym.gym_trainer` permission).\n\nStep 1 - Authenticate as trainer:\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\nStep 2 - Trainer clicks (or is delivered) the crafted link:\n\n```\nGET /en/user/2/trainer-login?next=https://evil.example/steal HTTP/1.1\nHost: target\nCookie: sessionid=[trainer1_session]\n\n-\u003e 302 Found\n   Location: https://evil.example/steal\n```\n\nStep 3 - Attacker server logs Referer:\n\n```\nReferer: http://target/en/user/2/trainer-login?next=https://evil.example/steal\n(victim user_pk and next URL exposed)\n```\n\nReproducibility: 2/2 runs.\n\n### Impact\n\nAn attacker who can deliver a crafted URL to a trainer (phishing email, malicious gym management system integration, social engineering) can redirect the trainer's browser to an attacker-controlled domain after the trainer enters impersonation mode. The redirect leaks:\n\n- The wger URL structure (including the impersonated user's `user_pk`) via the browser `Referer` header.\n- The session-rebound cookie (if the attacker page subsequently triggers an authenticated request with `credentials: 'include'` targeting wger, any same-site cookie without SameSite=Strict is attached).\n\nCombined with the trainer-login scope bypass (submitted separately), this primitive allows an attacker to silently impersonate arbitrary `gym=None` users and then land the trainer on an attacker page for credential harvesting.\n\n**Affected deployments**: every wger instance where `gym.gym_trainer` is delegated to non-admin users.\n\n**Severity**: Medium (CVSS 5.4). Network-reachable, low complexity, low privilege (trainer role), requires victim interaction (click), scope change (attacker's origin).","status":"published","published":"2026-05-06T19:50:52Z","modified":"2026-09-10T03:51:07.069599456Z","cvss":[{"version":"3.1","score":5.4,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N","level":"medium"}],"cwes":["CWE-601"],"updated_at":"2026-11-02T15:46:57.694388Z"}]}}
