VDB
EN
LOW 3.1

GHSA-42cr-w2gr-m54q

wger: IDOR via user-unscoped cache keys on routine API actions exposes workout data

상세

### Summary

Five routine detail action endpoints check a cache before calling `self.get_object()`. Cache keys are scoped only by `pk` — no user ID is included. When a victim has previously accessed their routine via the API, an attacker can retrieve the cached response for the same PK without any ownership check.

### Details

`wger/manager/api/views.py` — five actions follow this pattern (lines 134–201):

```python @action(detail=True) def date_sequence_display_mode(self, request, pk=None): cache_key = make_routine_api_date_sequence_display_cache_key(pk) cached = cache.get(cache_key) if cached: return Response(cached) # returned WITHOUT calling self.get_object() # only reaches ownership check on cache miss routine = self.get_object() ... ```

Cache key construction in `wger/utils/cache.py:89–106`:

```python def make_routine_api_date_sequence_display_cache_key(routine_id): return f"routine-api-date-sequence-display-{routine_id}" # No user ID in key ```

Cache TTL: 1 month (`4 * 604800` seconds, `settings_global.py:461`).

Affected endpoints: ``` GET /api/v2/routine/{pk}/date-sequence-display/ GET /api/v2/routine/{pk}/date-sequence-gym/ GET /api/v2/routine/{pk}/structure/ GET /api/v2/routine/{pk}/logs/ GET /api/v2/routine/{pk}/stats/ ```

### PoC

``` 1. Victim (user A) visits GET /api/v2/routine/5/structure/ → response cached under key "routine-api-structure-5" 2. Attacker (user B) visits GET /api/v2/routine/5/structure/ → cache hit → returns user A's routine structure without any ownership check ```

Requires the victim to have previously accessed the endpoint (cache must be populated). Once populated, the cache entry is valid for 1 month.

### Impact

An attacker with a registered account can retrieve another user's routine details — workout day sequences, exercise structure, training logs, and statistics — from cache without ownership verification.

**Fix**: Include the user ID in the cache key: ```python def make_routine_api_date_sequence_display_cache_key(routine_id, user_id): return f"routine-api-date-sequence-display-{user_id}-{routine_id}" ```

Or move `self.get_object()` before the cache lookup so ownership is always verified first.

이 버전이 영향받나요?

사용 중인 패키지 버전을 입력하면 즉시 평가합니다.

영향 패키지

PyPI / wger
최초 영향 버전: 0

No fixed version published yet for wger (pip). Pin to a known-safe version or switch to an alternative.

참고