🔀 오픈 리다이렉트 시뮬레이터 KISA #7 · 신뢰되지 않은 URL 접속
로그인/이동 엔드포인트가 요청 파라미터의 URL로 사용자를 그대로 리다이렉트합니다. 검증이 없으면 공격자는 신뢰 도메인을 미끼로 피싱 사이트로 우회시킬 수 있습니다.
① 취약한 엔드포인트: GET /login?next=... VULNERABLE
서버는 next 값을 읽어 아무 검증 없이 302 Location: {next}로 응답합니다. 아래 링크는 신뢰 은행 도메인을 가리키는 것처럼 보입니다.
② 안전한 엔드포인트: 허용목록 검증 SECURE
수정본은 next를 해석해 상대 경로이거나 명시적 허용목록 호스트일 때만 리다이렉트하고, 그 외에는 안전한 기본 경로로 폴백합니다.
③ 취약 vs 안전 코드
VULNERABLE
// Java (Spring) — 검증 없는 리다이렉트
@GetMapping("/login")
String login(@RequestParam String next){
// next 를 그대로 신뢰 → 외부 도메인 우회 가능
return "redirect:" + next;
}
SECURE
// 허용목록 + 상대경로만 허용
static final Set<String> ALLOW = Set.of("bank.example");
@GetMapping("/login")
String login(@RequestParam String next){
if(next.startsWith("/") && !next.startsWith("//"))
return "redirect:" + next; // 내부 상대경로 OK
try{ URI u = URI.create(next);
if(ALLOW.contains(u.getHost()))
return "redirect:" + next; // 허용 호스트만
}catch(Exception ignored){}
return "redirect:/dashboard"; // 안전 폴백
}
방어 핵심: 사용자 입력 URL을 그대로 리다이렉트하지 말 것 · 상대경로 또는 명시적 호스트 허용목록만 허용 ·
//host·역슬래시 우회 차단 · 외부 링크는 경유(주의) 페이지를 거치게 할 것.
⚠️ 교육용 시뮬레이션입니다. 모든 리다이렉트는 페이지 내부 mock 브라우저에서만 시연되며 실제 이동이나 외부 시스템 접근은 없습니다.