End a user's sessions when the account is deactivated
There is no token denylist in this product, so the JWT user loader is
the only place a deactivated account can be stopped, and it did a bare
lookup by id. Somebody deactivated at 09:00 kept a working access token
until it expired, and a refresh token that minted fresh ones for thirty
days.
/api/auth/refresh and the API-token path already checked isactive. This
makes the loader consistent with them rather than inventing policy.
Scope: product
(cherry picked from commit 9c1848fc61)
This commit is contained in:
@@ -98,7 +98,13 @@ from .plugins import plugin_manager
|
||||
# model internals. The endpoints plugin resolves a delivered script by name and
|
||||
# serves its body by digest to the agent. Additive name on the surface, minor
|
||||
# bump.
|
||||
__contract_version__ = '0.27.0'
|
||||
# 0.28.0: added client_ip and strip_port to shopdb.api so a plugin does not
|
||||
# hand-roll caller-IP extraction. Two plugins had, and both read the first
|
||||
# X-Forwarded-For hop, which the caller sends - so a rate limit keyed on it was
|
||||
# defeated by rotating the header. The helper resolves from remote_addr, which
|
||||
# ProxyFix has already filled from the header when TRUSTED_PROXY_COUNT says a
|
||||
# proxy is really in front. Additive names on the surface, minor bump.
|
||||
__contract_version__ = '0.28.0'
|
||||
|
||||
# Product release version (see ADR-007). The product version and the
|
||||
# plugin-contract version above are distinct series with independent
|
||||
@@ -211,7 +217,14 @@ def create_app(config_name: str = None) -> Flask:
|
||||
def user_lookup_callback(_jwt_header, jwt_data):
|
||||
from .core.models import User
|
||||
identity = jwt_data["sub"]
|
||||
return db.session.get(User, int(identity))
|
||||
user = db.session.get(User, int(identity))
|
||||
# Deactivating an account has to end its sessions. There is no token
|
||||
# denylist, so without this check the access token stays good until it
|
||||
# expires and the refresh token keeps minting new ones for 30 days.
|
||||
# /auth/refresh and the API-token path already check isactive.
|
||||
if user is None or not user.isactive:
|
||||
return None
|
||||
return user
|
||||
|
||||
@app.after_request
|
||||
def apply_security_headers(response):
|
||||
|
||||
Reference in New Issue
Block a user