OAuth Redirect URI 검증 우회 (WEB-53)

WEB-53 OAuth Redirect Bypass

OAuth Redirect URI 검증 우회:
OAuth 인증 서버에서 redirect_uri를 검증할 때, 정확한 매칭이 아닌 부분 매칭이나 느슨한 URL 파싱을 사용하면, 공격자가 악의적인 리다이렉션 URI로 Authorization Code를 탈취할 수 있습니다.

허용된 Redirect URI 목록

공격 시나리오

  1. 정상 플로우: 사용자가 앱에서 "Google로 로그인" 클릭
  2. 인증 요청: 앱이 OAuth 서버로 redirect_uri=https://app.example.com/callback 전송
  3. 검증 (취약): 서버가 "example.com 포함?" 또는 "도메인 일치?" 정도만 확인
  4. 공격: 공격자가 redirect_uri=https://app.example.com.attacker.com/callback로 변조
  5. 결과: Authorization Code가 attacker.com으로 리다이렉트됨
  6. 영향: 공격자가 Authorization Code를 탈취하여 사용자 계정 접근

공격 예시 목록

도메인 임베딩 (substring match 우회)
https://app.example.com.attacker.com/callback
파라미터로 정상 도메인 포함
https://attacker.com/callback?redirect=https://app.example.com
@ 문자 사용 (URL 파싱 오류)
https://example.com@attacker.com/callback
HTTP로 변경 (HTTPS 검증 부재)
http://app.example.com/callback
state 파라미터 포함
https://app.example.com.attacker.com/callback?state=abc

Redirect URI 검증

안전한 Redirect URI 검증

// 정확한 매칭 (권장)
$allowed_uris = [
  'https://app.example.com/callback',
  'https://trusted-site.com/auth/callback'
];

if (!in_array($redirect_uri, $allowed_uris, true)) {
  throw new Exception('Invalid redirect_uri');
}

// 또는 URL 파싱 + 도메인 화이트리스트
$parsed = parse_url($redirect_uri);
if ($parsed['scheme'] !== 'https' || 
    !in_array($parsed['host'], $allowed_hosts, true)) {
  throw new Exception('Invalid redirect_uri');
}