fix: gate support course-team GET on can-manage authorization
CourseTeamManageAPIView at lms/djangoapps/support/rest_api/v1/views.py declared only `permission_classes = (IsAuthenticated,)`, so any authenticated user — including a plain enrolled learner — could invoke GET and use the 404-vs-200 response for user enumeration against arbitrary email/username/user_id values, confirming which accounts exist and are active. Callers holding any course/org `instructor` role additionally received the target user's `staff`/`instructor` role map across the caller's scope. Gate `get()` on `_caller_can_manage_course_team()`, a new helper that returns True only for: - is_staff (GlobalStaff), or - is_superuser, or - SupportStaffRole, or - any user with a CourseAccessRole of role="instructor" This is the union of PUT's current authorization set (admin/staff/ superuser/instructor) and the global SupportStaffRole. Read access must match write access — a user who can PUT role changes must be able to see the current state before making them — and the endpoint lives in the support module, so support staff belong in the set too. Also extend `get_accessible_courses_for_user` so that SupportStaffRole users get the same all-courses view as admin/ staff, otherwise they'd fall through to the instructor branch and receive an empty result set. Anonymous callers still get 401 from DRF's IsAuthenticated; plain learners now get 403 before the target lookup runs, so the 404-vs- 200 enumeration discrepancy (CWE-204) is no longer reachable by unauthorized callers. Course instructors retain their scoped view. `put()` retains its existing authorization for now; it lacks SupportStaffRole in the set — a separate design gap best handled in a public follow-up after publication (cross-linked to GHSA-95xv-3c54-c3pw), where the `_caller_can_manage_course_team` helper can also become the shared PUT check. Fixes GHSA-95xv-3c54-c3pw. Credit: 5ud0 / Tarmo Technologies.
F
Feanil Patel committed
e2a1215f8d5da5170ddbf10316c2362e965e17bc
Parent: 71b09b8