T09 · Insecure Skill Coding Practices
- Location
templates/src/pages/AuthCallbackPage.tsx:34- Finding
OAuth State Is Not Cryptographically Generated or Validated by the Privileged Backend
- Content
View full analysis
{ // 生成state防CSRF const state = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15); sessionStorage.setItem('oauth_state', state); // 跳转授权页 const authUrl = new URL('https://go.second-me.cn/oauth/'); authUrl.searchParams.append('client_id', import.meta.env.VITE_SECONDME_CLIENT_ID); authUrl.searchParams.append('redirect_uri', import.meta.env.VITE_SECONDME_REDIRECT_URI); authUrl.searchParams.append('response_type', 'code'); authUrl.searchParams.append('state', state); window.location.href = authUrl.toString(); }; ``` ```typescript // templates/src/hooks/useSecondMe.ts:59-72 const login = useCallback(() => { const state = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15); sessionStorage.setItem('oauth_state', state); const authUrl = new URL('https://go.second-me.cn/oauth/'); authUrl.searchParams.append('client_id', import.meta.env.VITE_SECONDME_CLIENT_ID); authUrl.searchParams.append('redirect_uri', import.meta.env.VITE_SECONDME_REDIRECT_URI); authUrl.searchParams.append('response_type', 'code'); authUrl.searchParams.append('state', state); window.location.href = authUrl.toString(); }, []); ``` ```typescript // templates/src/pages/AuthCallbackPage.tsx:34-48 // 验证state const savedState = sessionStorage.getItem('oauth_state'); if (state !== savedState) { setError('安全验证失败'); setLoading(false); return; } sessionStorage.removeItem('oauth_s ...[truncated 2950 chars]- Remediation
View remediation
b.toString(16).padStart(2, '0')).join(''); ``` 2. Store a hash of the state server-side with: - A short expiration time. - Single-use semantics. - The intended redirect URI. - A binding to the initiating browser transaction. 3. Submit both `code` and `state` to the Edge Function. 4. Atomically validate and consume state in the Edge Function before exchanging the authorization code. Reject missing, expired, reused, or mismatched values. 5. Add OAuth PKCE: - Generate a cryptographically secure `code_verifier`. - Send its derived `code_challenge` in the authorization request. - Require the verifier during backend code exchange. 6. Remove the client-side state only after the backend transaction and Supabase session creation succeed. 7. Apply request rate limiting and return generic authentication errors without exposing internal details. ]]>
