Reduce MCP OAuth debug detail
This commit is contained in:
@@ -93,37 +93,6 @@ type MCPOAuthFlowErrorReason =
|
||||
|
||||
const MAX_LOCK_RETRIES = 5
|
||||
|
||||
/**
|
||||
* OAuth query parameters that should be redacted from logs.
|
||||
* These contain sensitive values that could enable CSRF or session fixation attacks.
|
||||
*/
|
||||
const SENSITIVE_OAUTH_PARAMS = [
|
||||
'state',
|
||||
'nonce',
|
||||
'code_challenge',
|
||||
'code_verifier',
|
||||
'code',
|
||||
]
|
||||
|
||||
/**
|
||||
* Redacts sensitive OAuth query parameters from a URL for safe logging.
|
||||
* Prevents exposure of state, nonce, code_challenge, code_verifier, and authorization codes.
|
||||
*/
|
||||
function redactSensitiveUrlParams(url: string): string {
|
||||
try {
|
||||
const parsedUrl = new URL(url)
|
||||
for (const param of SENSITIVE_OAUTH_PARAMS) {
|
||||
if (parsedUrl.searchParams.has(param)) {
|
||||
parsedUrl.searchParams.set(param, '[REDACTED]')
|
||||
}
|
||||
}
|
||||
return parsedUrl.toString()
|
||||
} catch {
|
||||
// Return as-is if not a valid URL
|
||||
return url
|
||||
}
|
||||
}
|
||||
|
||||
function summarizeHeadersForDebug(
|
||||
headers: Record<string, string> | undefined,
|
||||
): {
|
||||
@@ -1899,29 +1868,18 @@ export class ClaudeAuthProvider implements OAuthClientProvider {
|
||||
|
||||
// Extract and store scopes from the authorization URL for later use in token exchange
|
||||
const scopes = authorizationUrl.searchParams.get('scope')
|
||||
logMCPDebug(
|
||||
this.serverName,
|
||||
`Authorization URL: ${redactSensitiveUrlParams(authorizationUrl.toString())}`,
|
||||
)
|
||||
logMCPDebug(this.serverName, `Scopes in URL: ${scopes || 'NOT FOUND'}`)
|
||||
|
||||
if (scopes) {
|
||||
this._scopes = scopes
|
||||
logMCPDebug(
|
||||
this.serverName,
|
||||
`Captured scopes from authorization URL: ${scopes}`,
|
||||
)
|
||||
logMCPDebug(this.serverName, 'Captured scopes from authorization URL')
|
||||
} else {
|
||||
// If no scope in URL, try to get it from metadata
|
||||
const metadataScope = getScopeFromMetadata(this._metadata)
|
||||
if (metadataScope) {
|
||||
this._scopes = metadataScope
|
||||
logMCPDebug(
|
||||
this.serverName,
|
||||
`Using scopes from metadata: ${metadataScope}`,
|
||||
)
|
||||
logMCPDebug(this.serverName, 'Using scopes from metadata')
|
||||
} else {
|
||||
logMCPDebug(this.serverName, `No scopes available from URL or metadata`)
|
||||
logMCPDebug(this.serverName, 'No scopes available from URL or metadata')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1939,7 +1897,7 @@ export class ClaudeAuthProvider implements OAuthClientProvider {
|
||||
if (existing) {
|
||||
existing.stepUpScope = this._scopes
|
||||
storage.update(existingData)
|
||||
logMCPDebug(this.serverName, `Persisted step-up scope: ${this._scopes}`)
|
||||
logMCPDebug(this.serverName, 'Persisted step-up scope')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1960,8 +1918,6 @@ export class ClaudeAuthProvider implements OAuthClientProvider {
|
||||
}
|
||||
|
||||
logMCPDebug(this.serverName, `Redirecting to authorization URL`)
|
||||
const redactedUrl = redactSensitiveUrlParams(urlString)
|
||||
logMCPDebug(this.serverName, `Authorization URL: ${redactedUrl}`)
|
||||
|
||||
// Notify the UI about the authorization URL BEFORE opening the browser,
|
||||
// so users can see the URL as a fallback if the browser fails to open
|
||||
@@ -1970,7 +1926,7 @@ export class ClaudeAuthProvider implements OAuthClientProvider {
|
||||
}
|
||||
|
||||
if (!this.skipBrowserOpen) {
|
||||
logMCPDebug(this.serverName, `Opening authorization URL: ${redactedUrl}`)
|
||||
logMCPDebug(this.serverName, 'Opening authorization URL')
|
||||
|
||||
const success = await openBrowser(urlString)
|
||||
if (!success) {
|
||||
@@ -1982,7 +1938,7 @@ export class ClaudeAuthProvider implements OAuthClientProvider {
|
||||
} else {
|
||||
logMCPDebug(
|
||||
this.serverName,
|
||||
`Skipping browser open (skipBrowserOpen=true). URL: ${redactedUrl}`,
|
||||
'Skipping browser open (skipBrowserOpen=true)',
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -2035,7 +1991,7 @@ export class ClaudeAuthProvider implements OAuthClientProvider {
|
||||
}
|
||||
|
||||
storage.update(existingData)
|
||||
logMCPDebug(this.serverName, `Invalidated credentials (scope: ${scope})`)
|
||||
logMCPDebug(this.serverName, `Invalidated credentials (${scope})`)
|
||||
}
|
||||
|
||||
async saveDiscoveryState(state: OAuthDiscoveryState): Promise<void> {
|
||||
@@ -2043,10 +1999,7 @@ export class ClaudeAuthProvider implements OAuthClientProvider {
|
||||
const existingData = storage.read() || {}
|
||||
const serverKey = getServerKey(this.serverName, this.serverConfig)
|
||||
|
||||
logMCPDebug(
|
||||
this.serverName,
|
||||
`Saving discovery state (authServer: ${state.authorizationServerUrl})`,
|
||||
)
|
||||
logMCPDebug(this.serverName, 'Saving discovery state')
|
||||
|
||||
// Persist only the URLs, NOT the full metadata blobs.
|
||||
// authorizationServerMetadata alone is ~1.5-2KB per MCP server (every
|
||||
@@ -2085,10 +2038,7 @@ export class ClaudeAuthProvider implements OAuthClientProvider {
|
||||
|
||||
const cached = data?.mcpOAuth?.[serverKey]?.discoveryState
|
||||
if (cached?.authorizationServerUrl) {
|
||||
logMCPDebug(
|
||||
this.serverName,
|
||||
`Returning cached discovery state (authServer: ${cached.authorizationServerUrl})`,
|
||||
)
|
||||
logMCPDebug(this.serverName, 'Returning cached discovery state')
|
||||
|
||||
return {
|
||||
authorizationServerUrl: cached.authorizationServerUrl,
|
||||
|
||||
Reference in New Issue
Block a user