"URL의 시작은 실제 도메인이었는데, 클릭했더니 완전히 다른 사이트로 보내졌다" — 이것이 오픈 리디렉션입니다. 동작 원리와 확실하게 막는 방법을 설명합니다(공격 절차 없음).
왜 위험한가
핵심 피해는 도메인의 신뢰를 빌려주는 것입니다.
| 악용 방식 | 일어나는 일 |
|---|---|
| 피싱 발판 | 링크가 실제 도메인으로 시작 → 사용자와 필터가 신뢰 → 가짜 사이트로 이동 |
| 인증 흐름 탈취 | OAuth 형태의 흐름에서 리디렉션 대상을 변조해 토큰/코드를 가로챔 |
| 다른 버그 증폭 | SSRF 나 XSS 와 결합해 영향 범위를 넓힘 |
왜 통하는가
"로그인 후 사용자를 원래 있던 곳으로 되돌린다" 같은 기능에서 나타나며, 이때 복귀 URL이 신뢰되어 그대로 전달됩니다. 사용자가 보는 URL의 "시작"은 실제 도메인이므로, 끝까지 의심하기가 어렵습니다.
방어: 외부 URL을 받지 않기
상대 경로만 허용 (가장 중요)
/dashboard 같은 복귀 대상은 상대 경로만 받아들이고, 전체 URL(http:// 나 // 로 시작하는 것)은 거부하세요. 사용자가 목적지 도메인을 지정할 여지를 전혀 주지 마세요.
허용 목록과 대조
동적 대상이 필요하다면, 알려진 목적지의 고정된 집합(매핑)에 있는 항목만 허용하세요. 그 외에는 기본 페이지로 폴백합니다.
문자열 검사에 의존하지 않기
//evil, 역슬래시, @, 다중 인코딩이 단순한 필터를 우회합니다. 필터에 땜질하지 말고 받아들이는 대상 자체를 바꾸세요(상대 경로 + 허용 목록).
외부로 나가야 한다면 명시적으로
외부 리디렉션이 의도된 것이라면 안내 페이지("외부 사이트로 이동합니다")를 표시하세요. 조용히 전달하지 마세요.
본 사이트의 견해: 단독으로는 '낮음'이지만, 피싱과 짝지으면 강력하다
오픈 리디렉션은 단독으로는 위험도가 낮게 평가되는 경우가 많지만, 도메인의 신뢰를 빌려주기 때문에 피싱이나 인증 탈취와 결합하면 강력해집니다. 그래서 설계 차원의 조치 — 상대 경로 + 허용 목록 — 가 근본을 효율적으로 제거합니다. 이는 SSRF(서버가 임의의 곳에 접속하게 만드는 것)와 닮아 있습니다. 둘 다 목적지를 사용자가 결정하게 두지 않는다는 방어 원칙을 공유합니다.
다음으로 읽기
FAQ
Q오픈 리디렉션은 왜 문제가 되나요?
URL의 앞부분 도메인은 실제로 신뢰받는 도메인(예: 로그인 페이지)이므로 사용자와 메일 필터가 안심하고 클릭합니다. 그런데 사이트가 그들을 임의의 외부 사이트로 넘겨 보내, 실제 도메인이 피싱의 발판이 되고 인증 흐름에서 토큰을 탈취하는 발판이 됩니다.
Q가장 효과적인 방어법은 무엇인가요?
외부 URL을 리디렉션 대상으로 받지 않는 것입니다. 로그인 후 복귀 경로의 경우, 상대 경로(/dashboard)만 허용하고 허용 목록(알려진 목적지의 고정된 집합)과 대조하세요. 정말로 사용자를 외부로 보내야 한다면, 외부로 나간다는 사실을 알리는 안내 페이지를 표시하세요.
Qhttp:// 만 검사하면 충분한가요?
아닙니다. 스킴이 없는 형태(//evil.example), 역슬래시, 인코딩, @ 기반의 헷갈리는 URL이 모두 단순 검사를 우회합니다. 문자열을 판단하기보다, 애초에 외부 URL을 전혀 받지 않도록 설계하세요(상대 경로 + 허용 목록).