DataTalksClub / DataTalksClub/course-management-platform
stop_impersonating is CSRF-exempt — find root cause and restore protection
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 85
- Forks
- 37
- PR merge metrics
- No merged PRs in 30d
Description
Summary
The stop_impersonating view was made @csrf_exempt in f644e5a to unblock staff returning to their own account after impersonating a user. The impersonation-stop POST was failing CSRF verification. Exempting the view works around the symptom but masks the real cause and should be treated as temporary.
Why this is not just cosmetic
The banner form already renders {% csrf_token %} (templates/base.html:67), so this is not a missing-token problem. A token is being sent and is still being rejected — something environmental is rejecting a valid request, and we don't currently know what. If we don't understand why it fails here, we can't be sure it isn't (or won't start) failing on other POST forms.
Risk assessment
Practical risk on this specific endpoint is low: stop_impersonating only calls restore_original_login and redirects. It is @login_required and @require_POST. The worst a CSRF attacker achieves is forcing a staff member who is currently impersonating to drop back to their own account — a de-escalation, not a privilege gain, with no data mutation.
The concern is not this endpoint today, it's that:
@csrf_exemptmasks an unexplained CSRF failure.- It sets a precedent that becomes dangerous the moment someone adds real logic to the view.
Likely root causes (to investigate)
The Django CSRF rejection log line states the exact reason. Candidates, most to least likely:
- Origin/Referer rejection behind the proxy.
CSRF_TRUSTED_ORIGINSis derived fromALLOWED_HOSTS/ theEXTRA_ALLOWED_HOSTSenv var (course_management/settings.py:42-46). Ifdev.courses.datatalks.clubisn't in that env var, HTTPS POSTs get "Origin checking failed" — though this would affect all forms, not just this one. - Stale/cached token. If the banner-bearing page is served from a cache, the rendered token won't match the user's current
csrftokencookie. This would be page-specific. - CSRF cookie lost across the django-loginas session rotation, possibly interacting with
CSRF_COOKIE_SECURE/SameSitebehind the TLS-terminating proxy (SECURE_PROXY_SSL_HEADERis set atsettings.py:318).
Proposed fix
- Pull the actual CSRF failure reason from dev logs (or reproduce locally) to identify which cause above applies.
- Apply the targeted fix:
- Origin issue → add the host to
EXTRA_ALLOWED_HOSTS. - Caching issue →
@never_cachethe banner-bearing view (keeps CSRF protection). - Cookie issue → fix the cookie flag / proxy config.
- Origin issue → add the host to
- Remove
@csrf_exemptfromstop_impersonating(accounts/views.py:62) once the real cause is fixed.
References
- Commit: f644e5a "Exempt stop_impersonating from CSRF"
accounts/views.py:61-66templates/base.html:66-71course_management/settings.py:42-46,:318
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the CSRF failure reason in development logs and the impersonation flow in accounts/views.py:61-66. Check the banner form in templates/base.html:66-71 and the host, proxy, and cookie settings in course_management/settings.py:42-46 and :318, then reproduce the POST if needed. Done means the root cause is fixed, CSRF protection remains enabled, and @csrf_exempt is removed from stop_impersonating.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- django, python
- Domain
- authentication, backend, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100