From 058fd28db8d6abcab9c5fa88bb207f534bb54d95 Mon Sep 17 00:00:00 2001 From: Tanner Prestegard <tanner.prestegard@ligo.org> Date: Tue, 9 Apr 2019 13:46:56 -0500 Subject: [PATCH] Prevent certificate or basic auth on AJAX requests to the API Discovered that AJAX requests to the API from the web view were using certificates in people's browsers even if they were logged out of the Django session. So when they wanted to view the page as a public user they still saw some extra information. No security risk since they needed to have a valid certificate anyway, but a bit annoying. --- gracedb/api/backends.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/gracedb/api/backends.py b/gracedb/api/backends.py index 02f6df921..5b2d2fffe 100644 --- a/gracedb/api/backends.py +++ b/gracedb/api/backends.py @@ -22,6 +22,7 @@ logger = logging.getLogger(__name__) class GraceDbBasicAuthentication(authentication.BasicAuthentication): + allow_ajax = False api_only = True def authenticate(self, request, *args, **kwargs): @@ -33,6 +34,11 @@ class GraceDbBasicAuthentication(authentication.BasicAuthentication): if self.api_only and not is_api_request(request.path): return None + # Don't allow this auth type for AJAX requests, since we don't want it + # to work for API requests made by the web views. + if request.is_ajax() and not self.allow_ajax: + return None + # Call base class authenticate() method return super(GraceDbBasicAuthentication, self).authenticate(request) @@ -62,6 +68,7 @@ class GraceDbX509Authentication(authentication.BaseAuthentication): Authentication based on X509 certificate subject. Certificate should be verified by Apache already. """ + allow_ajax = False api_only = True www_authenticate_realm = 'api' subject_dn_header = getattr(settings, 'X509_SUBJECT_DN_HEADER', @@ -75,6 +82,13 @@ class GraceDbX509Authentication(authentication.BaseAuthentication): if self.api_only and not is_api_request(request.path): return None + # Don't allow this auth type for AJAX requests - this is because + # users with certificates in their browser can still authenticate via + # this mechanism in the web view (since it makes API queries), even + # when they are not logged in. + if request.is_ajax() and not self.allow_ajax: + return None + # Try to get credentials from request headers. user_cert_dn = self.get_cert_dn_from_request(request) @@ -166,6 +180,7 @@ class GraceDbX509CertInfosAuthentication(GraceDbX509Authentication): Authentication based on X509 "infos" header. Certificate should be verified by Traefik already. """ + allow_ajax = False api_only = True infos_header = getattr(settings, 'X509_INFOS_HEADER', 'HTTP_X_FORWARDED_TLS_CLIENT_CERT_INFOS') -- GitLab