클라이언트 측 검증되지 않은 URL 리다이렉트 (Open Redirect)
Open Redirect (Client-Side)
설명
클라이언트 측 Open Redirect는 사용자가 제어할 수 있는 값(쿼리스트링, 해시, DOM 값 등)을 그대로 location.assign/replace/href 등에 넣어 리다이렉트할 때 발생합니다. 검증 없이 외부 URL로 이동이 가능해지면 공격자가 조작한 링크를 통해 사용자를 신뢰된 사이트에서 악성 사이트로 보내 피싱이나 토큰 탈취를 유도할 수 있습니다. 예를 들어, 신뢰된 도메인의 링크에 to 파라미터를 악성 도메인으로 설정하면 사용자는 페이지 로드 후 자동으로 악성 사이트로 이동합니다.
잠재적 영향
피싱/자격 증명 탈취: 사용자를 공격자 사이트로 유도해 로그인 정보, MFA 코드 등을 입력하게 만듭니다.
OAuth 토큰/코드 탈취: Open Redirect 체인을 이용해 redirect_uri 검증 우회를 시도하여 Authorization Code나 Access Token을 가로챌 수 있습니다.
악성코드 배포 및 브랜드 훼손: 신뢰된 도메인을 경유해 악성 다운로드로 이동시키고, 서비스 신뢰도를 떨어뜨립니다.
보안 정책 우회: 리퍼러 기반 필터링이나 일부 네비게이션 보호 논리를 우회해 외부로 이동시킬 수 있습니다.
해결 방법
사용자 입력을 리다이렉트에 직접 사용하지 마세요.
허용 목록(allowlist) 기반 매핑: to=home 같은 키를 내부 경로로 매핑하고 목록 외 값은 기본 경로로 처리합니다.
내부 경로만 허용: 스킴(http, https)이나 호스트가 있는 절대 URL, 프로토콜 상대 URL(//evil.com)은 차단합니다.
URL 검증: new URL(value, location.origin)으로 파싱 후 origin이 현재 사이트와 동일한지, pathname이 '/'로 시작하는지 확인합니다.
서버와 클라이언트 모두에서 검증: 가능하면 서버에서 최종 리다이렉트 수행 시에도 동일한 allowlist 검사를 적용하세요.
취약한 코드 및 안전한 코드 예시
취약한 코드
안전한 코드
설명:
취약한 코드: 사용자 제어 값(raw)을 그대로 location에 대입하여 절대 URL(https://..., //evil.com 등)도 허용합니다. 공격자는 신뢰된 도메인의 링크에 #to=외부URL을 붙여 사용자를 악성 사이트로 자동 이동시켜 피싱과 토큰 탈취를 유도할 수 있습니다.
안전한 코드: 사용자 입력을 직접 사용하지 않고, 사전에 정의한 allowlist 키를 내부 경로로만 매핑합니다. 외부 도메인이나 절대 URL은 선택지에 없으므로 리다이렉트가 내부로만 제한되어 Open Redirect 위험이 제거됩니다.
참조
Last updated