The custom admin actions for sponsorships and contracts (registered in
apps/sponsors/admin.py via self.admin_site.admin_view(...)) can be
tightened in two ways. This was reported privately to the PSF Security Team,
who suggested opening a public issue as a hardening opportunity since it
requires an existing staff account.
1. Custom admin actions don't enforce the per-model permission
AdminSite.admin_view verifies is_active + is_staff only, not the
model's change permission, so any staff user can drive the sponsorship /
contract workflow actions (approve / reject / lock / unlock / send /
execute / nullify / ...) regardless of their assigned sponsors
permissions.
2. lock mutates on a GET (no confirmation / CSRF token)
views_admin.lock_view sets locked = True and saves on a plain GET, with
no method check and no confirmation step — unlike its sibling unlock_view,
which renders a confirmation page and only mutates on POST.
Proposed hardening
- Require the model change permission on each custom admin action URL.
- Give
lock the same POST + confirmation flow unlock already uses.
I have a PR ready.
The custom admin actions for sponsorships and contracts (registered in
apps/sponsors/admin.pyviaself.admin_site.admin_view(...)) can betightened in two ways. This was reported privately to the PSF Security Team,
who suggested opening a public issue as a hardening opportunity since it
requires an existing staff account.
1. Custom admin actions don't enforce the per-model permission
AdminSite.admin_viewverifiesis_active+is_staffonly, not themodel's change permission, so any staff user can drive the sponsorship /
contract workflow actions (approve / reject / lock / unlock / send /
execute / nullify / ...) regardless of their assigned
sponsorspermissions.
2.
lockmutates on a GET (no confirmation / CSRF token)views_admin.lock_viewsetslocked = Trueand saves on a plain GET, withno method check and no confirmation step — unlike its sibling
unlock_view,which renders a confirmation page and only mutates on POST.
Proposed hardening
lockthe same POST + confirmation flowunlockalready uses.I have a PR ready.