diff --git a/src/sentry/templates/sentry/toolbar/iframe.html b/src/sentry/templates/sentry/toolbar/iframe.html index a488d33d093668..e2ee55644ead32 100644 --- a/src/sentry/templates/sentry/toolbar/iframe.html +++ b/src/sentry/templates/sentry/toolbar/iframe.html @@ -98,11 +98,15 @@ } const loginWindowMessageDispatch = { - 'did-login': ({ cookie, token }) => { + 'did-login': ({ cookie, csrfToken, token }) => { if (cookie) { document.cookie = getCookieValue(cookie, window.location.hostname); log('Saved a cookie', document.cookie.indexOf(cookie) >= 0); } + if (csrfToken) { + sessionStorage.setItem('csrfToken', csrfToken); + log('Saved a CSRF token to sessionStorage'); + } if (token) { localStorage.setItem('accessToken', token); log('Saved an accessToken to localStorage'); @@ -135,6 +139,9 @@ document.cookie = getCookieValue(cookie, regionUrl); log('Cleared the current cookie'); + sessionStorage.removeItem('csrfToken'); + log('Removed CSRF token from sessionStorage'); + const accessToken = localStorage.removeItem('accessToken') log('Removed accessToken from localStorage'); @@ -150,6 +157,9 @@ const accessToken = localStorage.getItem('accessToken'); const bearer = accessToken ? { 'Authorization': `Bearer ${accessToken}` } : {}; + const csrfToken = sessionStorage.getItem('csrfToken'); + const csrfHeader = csrfToken ? { 'X-CSRFToken': csrfToken } : {}; + // If either of these is invalid, or both are missing, we will // forward the resulting 401 to the application, which will request // tokens be destroyed and reload the iframe in an unauth state. @@ -158,7 +168,7 @@ const url = new URL('/api/0' + path, organizationUrl); const initWithCreds = { ...init, - headers: { ...init.headers, ...bearer }, + headers: { ...init.headers, ...bearer, ...csrfHeader }, credentials: 'include', }; const response = await fetch(url, initWithCreds); diff --git a/src/sentry/templates/sentry/toolbar/login-success.html b/src/sentry/templates/sentry/toolbar/login-success.html index 83af6518d00f51..522e58e20201e4 100644 --- a/src/sentry/templates/sentry/toolbar/login-success.html +++ b/src/sentry/templates/sentry/toolbar/login-success.html @@ -24,6 +24,8 @@

You're logged in!

const orgSlug = '{{ organization_slug|escape }}'; const delay = {{ delay_ms|escapejs }}; const cookie = '{{ cookie|escapejs }}'; + const csrfCookieName = '{{ csrf_cookie_name|escapejs }}'; + const csrfToken = document.cookie.split(';').find(c => c.trim().startsWith(csrfCookieName + '='))?.split('=')[1] ?? ''; const token = '{{ token|escapejs }}'; if (window.location.origin === 'https://sentry.io') { @@ -42,6 +44,7 @@

You're logged in!

source: 'sentry-toolbar', message: 'did-login', cookie, + csrfToken, token, }, window.location.origin); diff --git a/src/sentry/toolbar/views/login_success_view.py b/src/sentry/toolbar/views/login_success_view.py index c4d4c256017796..ac68e7ec49ffe7 100644 --- a/src/sentry/toolbar/views/login_success_view.py +++ b/src/sentry/toolbar/views/login_success_view.py @@ -6,8 +6,7 @@ TEMPLATE = "sentry/toolbar/login-success.html" session_cookie_name = settings.SESSION_COOKIE_NAME - -# touch 123 +csrf_cookie_name = settings.CSRF_COOKIE_NAME @region_silo_view @@ -22,6 +21,7 @@ def get(self, request: HttpRequest, organization, project_id_or_slug): "delay_sec": int(delay_ms / 1000), "delay_ms": delay_ms, "cookie": f"{session_cookie_name}={request.COOKIES.get(session_cookie_name)}", + "csrf_cookie_name": csrf_cookie_name, "token": "", }, )