Repository navigation
Authorise on the acting role, and stop an upload from being a page - #2000
Merged
vikrantwiz02 merged 4 commits intoSep 30, 2026
Merged
vikrantwiz02 merged 4 commits into
vikrantwiz02 merged 4 commits into
Conversation
role_required checked the set of designations somebody holds, so a student who also holds an office kept that office's authority while acting as a student — and anything reaching their session reached the office's endpoints with it. It now checks the acting role, defaulting to the office when the switcher has never been used, so nobody is locked out. Keyed on HoldsDesignation.working rather than user, which is what the model's own docstring asks for and what the IAM already projects: reading the other one authorises somebody on leave and refuses their stand-in. update_last_selected_role accepted any string and stored it. That was harmless while it only drove the sidebar and a free promotion once authorisation reads it, so a post nobody holds is now refused.
Uploads are served from the same origin as the portal and every module framed inside it, so a file served inline runs as the application: an uploaded .html or .svg would execute in this origin and could read the API token the client keeps in localStorage. Forcing attachment, nosniff and a sandbox policy takes that away whatever the file claims to be, and holds whether or not the media route is reachable.
A DRF token never expires, and this one lives in localStorage where any script on the origin can read it, so a copy taken once works for good. The class is here; the settings switch is deployment's to make. The IAM session cookie was secure only when an environment variable said so. It now follows DEBUG, still overridable, so one plain-HTTP request no longer puts the session on the wire.
…tests The reply waited on the full SMTP round-trip although the OTP row is already saved before the send and the caller is told the same thing either way — so the wait bought nothing. It now goes to a thread. Tests for the parts that decide access: the acting role, a stand-in against the absent holder, a role no longer held, an upload served as a download, and a token past its life.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Four security fixes in the portal, found while reviewing what the single login and single sidebar expose.
Authority follows the acting role
role_requiredchecked the set of designations somebody holds. A student who also holds an office kept that office's authority while acting as a student, so anything reaching their session — an XSS above all — reached the office's endpoints with it. It now checks the role being acted in, defaulting to the office when the switcher has never been used, so nobody is locked out.Keyed on
HoldsDesignation.workinginstead ofuser, which is what the model's own docstring asks for and what the IAM already projects. Reading the other one authorises somebody on leave and refuses their stand-in.update_last_selected_roleaccepted any string and stored it — harmless while it only drove the sidebar, a free promotion once authorisation reads it. A post nobody holds is now refused.An upload is a download, never a page
Uploads are served from the same origin as the portal and every module framed inside it. A file served inline runs as the application, so an uploaded
.htmlor.svgwould execute in this origin and could read the API token the client keeps inlocalStorage. They now go out asattachmentwithnosniffand a sandbox policy, whatever the file claims to be.Credentials that stop working
A DRF token never expires and this one lives in
localStorage, so a copy taken once works for good.ExpiringTokenAuthenticationbounds it; the settings switch is deployment's to make. The IAM session cookie was secure only when an environment variable said so, and now followsDEBUG.OTP off the request path
The reply waited on the full SMTP round-trip, although the OTP row is saved before the send and the caller is told the same thing either way. It now goes to a thread.
Tests
12 new, covering the parts that decide access: the acting role, a stand-in against the absent holder, a role no longer held, an upload served as a download, a token past its life, and a slow mail host not holding the request. 50 pass in this app.
Not in this PR
DEBUG = True,CORS_ORIGIN_ALLOW_ALL, the committed Google and database credentials, and the transport-security settings are all inFusion/settings/, which the deployment overwrites. They are being applied on the server, and the two secrets need rotating.