wger, Open Redirect, N/A (Medium)

Listen to this Post

How the Vulnerability Works

The trainer_login view in wger/core/views/user.py (line 203) accepts a `next` parameter via the HTTP GET method. After the impersonation logic completes, the view returns an `HttpResponseRedirect` using the value of `request.GET.get(‘next’)` directly, without any validation of the host or scheme. This missing call to Django’s `url_has_allowed_host_and_scheme()` allows an attacker to supply a fully qualified external URL (e.g., https://evil.example/steal`). When a logged‑in trainer clicks a crafted link like `/en/user/2/trainer-login?next=https://evil.example/steal`, the server responds with a `302 Found redirect whose `Location` header contains the attacker‑controlled URL. The trainer’s browser is immediately sent to the malicious site, leaking the wger URL structure (including the impersonated user’s user_pk) via the `Referer` header. If the attacker’s page later triggers an authenticated request with credentials: 'include', any session cookie without `SameSite=Strict` is attached. Combined with a trainer‑login scope bypass, this primitive can lead to silent impersonation of arbitrary users and credential harvesting. The issue is network‑reachable, requires low attacker privileges (trainer role) and victim interaction (a click), and changes the security scope to the attacker’s origin, yielding a CVSS score of 5.4 (Medium).

DailyCVE Form

Platform: wger
Version: 2.5 and below
Vulnerability : Open redirect
Severity: Medium
date: 2026-04-28

Prediction: 2026-05-15

What Undercode Say

Check if instance is vulnerable
curl -I "https://target/en/user/2/trainer-login?next=https://evil.example/steal"
Expected: 302 Found with Location: https://evil.example/steal
Simulate a trainer login and capture the redirect
curl -X GET "https://target/en/user/2/trainer-login?next=https://evil.example/steal" \
-H "Cookie: sessionid=trainer1_session" \
-v

Exploit

GET /en/user/2/trainer-login?next=https://evil.example/steal HTTP/1.1
Host: target
Cookie: sessionid=trainer1_session

Server responds with:

HTTP/1.1 302 Found
Location: https://evil.example/steal

The trainer’s browser is redirected to https://evil.example/steal`, leaking the `Referer` header which contains the wger URL and the `next` parameter.
<h2 style="color: blue;">Protection from this CVE</h2>
- Apply the suggested patch: use `url_has_allowed_host_and_scheme()` to validate the `next` parameter before redirecting.
- Alternatively, change the `trainer_login` view to `@require_POST` so the `next` parameter is moved to the POST body where CSRF protection applies.
- Update wger to the latest version once the official patch is released.
- As a workaround, manually add `url_has_allowed_host_and_scheme()` validation in `wger/core/views/user.py` around line 203.
<h2 style="color: blue;">Impact</h2>
An attacker who can deliver a crafted URL to a trainer (e.g., via a phishing email or a malicious gym management integration) can redirect the trainer’s browser to an attacker‑controlled domain immediately after impersonation mode is entered. This leaks the wger URL structure (including the impersonated user’s
user_pk) via the `Referer` header. If the attacker’s page subsequently makes authenticated requests withcredentials: ‘include’`, any session cookie without `SameSite=Strict` will be attached, enabling session rebound. Combined with a trainer‑login scope bypass, this can lead to silent impersonation of arbitrary `gym=None` users and credential harvesting. Every wger instance where the `gym.gym_trainer` permission is delegated to non‑admin users is affected.

🎯Let’s Practice Exploiting & Learn Patching For Free:

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top