From e42b083f205fd5951936a28c0939c6a0fbd8d6d6 Mon Sep 17 00:00:00 2001 From: lebaudantoine Date: Tue, 30 Jun 2026 16:23:49 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=82(backend)=20reject=20user=20access?= =?UTF-8?q?=20tokens=20on=20the=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The original implementation, introduced two years ago, was incorrect and exposed the API to an undesired authentication mode: any user access token obtained for a given user was being accepted as valid credentials on the external API. Restrict authentication to the intended mode so that user access tokens are no longer accepted on this API. Thanks @lunika spotting this. --- CHANGELOG.md | 4 ++++ src/backend/core/authentication/backends.py | 15 +++++++++++++++ src/backend/meet/settings.py | 3 +-- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86fe203f..47abeee3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,10 @@ and this project adheres to - ♻️(env) refactor env variables handling - 🚸(frontend) use "Advanced" instead of "Premium" in the sidepanel +### Fixed + +- 🛂(backend) reject user access tokens on the API + ## [1.21.0] - 2026-06-15 ### Added diff --git a/src/backend/core/authentication/backends.py b/src/backend/core/authentication/backends.py index 64a962c9..0cb0e034 100644 --- a/src/backend/core/authentication/backends.py +++ b/src/backend/core/authentication/backends.py @@ -9,6 +9,7 @@ from django.utils.translation import gettext_lazy as _ from lasuite.oidc_login.backends import ( OIDCAuthenticationBackend as LaSuiteOIDCAuthenticationBackend, ) +from rest_framework.authentication import SessionAuthentication from core.models import User from core.services.marketing import ( @@ -96,3 +97,17 @@ class OIDCAuthenticationBackend(LaSuiteOIDCAuthenticationBackend): "Multiple user accounts share a common email." ) from e return None + + +class SessionAuthenticationWith401(SessionAuthentication): + """ + Identical to DRF's SessionAuthentication, but returns a WWW-Authenticate + header so unauthenticated requests get a 401 instead of a 403. + + The scheme is deliberately NOT 'Basic' — that would trigger the browser's + native login popup. 'Session' is ignored by the browser's auth UI but is + still truthy, so DRF keeps the status at 401. + """ + + def authenticate_header(self, request): + return "Session" diff --git a/src/backend/meet/settings.py b/src/backend/meet/settings.py index 72d6fbd5..f8988273 100755 --- a/src/backend/meet/settings.py +++ b/src/backend/meet/settings.py @@ -323,8 +323,7 @@ class Base(Configuration): REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ( - "mozilla_django_oidc.contrib.drf.OIDCAuthentication", - "rest_framework.authentication.SessionAuthentication", + "core.authentication.backends.SessionAuthenticationWith401", ), "DEFAULT_PARSER_CLASSES": [ "rest_framework.parsers.JSONParser",