Admin Dashboard enhancements, OAuth session fixes, and tracking script improvements #37

Merged
uz1mani merged 9 commits from staging into main 2026-02-27 12:27:37 +00:00
17 changed files with 532 additions and 1012 deletions
Showing only changes of commit 1edd78672e - Show all commits

View File

@@ -56,12 +56,15 @@ function AuthCallbackContent() {
const storedState = localStorage.getItem('oauth_state') const storedState = localStorage.getItem('oauth_state')
const codeVerifier = localStorage.getItem('oauth_code_verifier') const codeVerifier = localStorage.getItem('oauth_code_verifier')
// * Full OAuth flow (app-initiated): validate state + use PKCE // * Session flow (from auth hub): redirect has code but no state. Clear stale PKCE
// * Session-authorized flow (from auth hub): no stored state or verifier // * data from any previous app-initiated OAuth so exchange proceeds without validation.
const isFullOAuth = !!storedState && !!codeVerifier if (!state) {
localStorage.removeItem('oauth_state')
if (isFullOAuth) { localStorage.removeItem('oauth_code_verifier')
if (state !== storedState) { } else {
// * Full OAuth flow (app-initiated): validate state + use PKCE
const isFullOAuth = !!storedState && !!codeVerifier
if (isFullOAuth && state !== storedState) {
logger.error('State mismatch', { received: state, stored: storedState }) logger.error('State mismatch', { received: state, stored: storedState })
setError('Invalid state') setError('Invalid state')
greptile-apps[bot] commented 2026-02-27 12:30:49 +00:00 (Migrated from github.com)
Review

Accepting OAuth callbacks without state parameter creates a CSRF vulnerability. An attacker could craft a malicious callback URL with their own authorization code and trick users into executing it, logging them into the attacker's account.

The PR description mentions "trusted origins" but there's no code validating the origin. At minimum, check document.referrer to ensure it starts with the auth domain when state is missing:

// * Session flow (from auth hub): redirect has code but no state. Clear stale PKCE
// * data from any previous app-initiated OAuth so exchange proceeds without validation.
if (!state) {
  // * Verify callback came from trusted auth domain to prevent CSRF
  if (typeof document !== 'undefined' && document.referrer) {
    const referrerUrl = new URL(document.referrer)
    const authUrl = new URL(AUTH_URL)
    if (referrerUrl.origin !== authUrl.origin) {
      logger.error('Stateless callback from untrusted origin', { referrer: document.referrer })
      setError('Invalid state')
      return
    }
  }
  localStorage.removeItem('oauth_state')
  localStorage.removeItem('oauth_code_verifier')
Prompt To Fix With AI
This is a comment left during a code review.
Path: app/auth/callback/page.tsx
Line: 59-63

Comment:
Accepting OAuth callbacks without `state` parameter creates a CSRF vulnerability. An attacker could craft a malicious callback URL with their own authorization code and trick users into executing it, logging them into the attacker's account.

The PR description mentions "trusted origins" but there's no code validating the origin. At minimum, check `document.referrer` to ensure it starts with the auth domain when `state` is missing:

```suggestion
// * Session flow (from auth hub): redirect has code but no state. Clear stale PKCE
// * data from any previous app-initiated OAuth so exchange proceeds without validation.
if (!state) {
  // * Verify callback came from trusted auth domain to prevent CSRF
  if (typeof document !== 'undefined' && document.referrer) {
    const referrerUrl = new URL(document.referrer)
    const authUrl = new URL(AUTH_URL)
    if (referrerUrl.origin !== authUrl.origin) {
      logger.error('Stateless callback from untrusted origin', { referrer: document.referrer })
      setError('Invalid state')
      return
    }
  }
  localStorage.removeItem('oauth_state')
  localStorage.removeItem('oauth_code_verifier')
```

How can I resolve this? If you propose a fix, please make it concise.
Accepting OAuth callbacks without `state` parameter creates a CSRF vulnerability. An attacker could craft a malicious callback URL with their own authorization code and trick users into executing it, logging them into the attacker's account. The PR description mentions "trusted origins" but there's no code validating the origin. At minimum, check `document.referrer` to ensure it starts with the auth domain when `state` is missing: ```suggestion // * Session flow (from auth hub): redirect has code but no state. Clear stale PKCE // * data from any previous app-initiated OAuth so exchange proceeds without validation. if (!state) { // * Verify callback came from trusted auth domain to prevent CSRF if (typeof document !== 'undefined' && document.referrer) { const referrerUrl = new URL(document.referrer) const authUrl = new URL(AUTH_URL) if (referrerUrl.origin !== authUrl.origin) { logger.error('Stateless callback from untrusted origin', { referrer: document.referrer }) setError('Invalid state') return } } localStorage.removeItem('oauth_state') localStorage.removeItem('oauth_code_verifier') ``` <details><summary>Prompt To Fix With AI</summary> `````markdown This is a comment left during a code review. Path: app/auth/callback/page.tsx Line: 59-63 Comment: Accepting OAuth callbacks without `state` parameter creates a CSRF vulnerability. An attacker could craft a malicious callback URL with their own authorization code and trick users into executing it, logging them into the attacker's account. The PR description mentions "trusted origins" but there's no code validating the origin. At minimum, check `document.referrer` to ensure it starts with the auth domain when `state` is missing: ```suggestion // * Session flow (from auth hub): redirect has code but no state. Clear stale PKCE // * data from any previous app-initiated OAuth so exchange proceeds without validation. if (!state) { // * Verify callback came from trusted auth domain to prevent CSRF if (typeof document !== 'undefined' && document.referrer) { const referrerUrl = new URL(document.referrer) const authUrl = new URL(AUTH_URL) if (referrerUrl.origin !== authUrl.origin) { logger.error('Stateless callback from untrusted origin', { referrer: document.referrer }) setError('Invalid state') return } } localStorage.removeItem('oauth_state') localStorage.removeItem('oauth_code_verifier') ``` How can I resolve this? If you propose a fix, please make it concise. ````` </details>
return return