🔀 오픈 리다이렉트 시뮬레이터 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 브라우저에서만 시연되며 실제 이동이나 외부 시스템 접근은 없습니다.