The OAuth2 token refresh endpoint (POST /api/v1/oauth2-credential/refresh/:credentialId) is in WHITELIST_URLS, meaning it requires no authentication. It decrypts the stored credential (containing clientId, clientSecret, refresh_token), sends a refresh request to the configured OAuth provider, and returns the new access_token directly in the response body.
Whitelist entry at packages/server/src/utils/constants.ts:40.
Attack Chain
Attacker obtains a credential ID (via Finding 2 / public chatflow leak, or enumeration)
Attacker calls POST /api/v1/oauth2-credential/refresh/:credentialId (no auth required)
Server decrypts credential, sends refresh request to OAuth provider with user's client_secret
Server returns the new access_token in the response to the attacker
Attacker uses the token to access the victim's connected service (Google, Microsoft, etc.)
Docker Validation
POST /api/v1/oauth2-credential/refresh/fake-uuid returns {"message":"Credential not found"} (not 401 Unauthorized), proving the endpoint processes the request without authentication.
Impact
OAuth2 access token theft for any connected service
Full access to the victim's third-party accounts (Google, Microsoft, GitHub, etc.)
Client secret transmitted to OAuth provider during refresh
Can also be used for DoS by exhausting refresh token quota
Suggested Fix
Remove the refresh endpoint from WHITELIST_URLS and require authentication:
// Remove from WHITELIST_URLS in constants.ts
// Add authentication check in the route handler