본문 바로가기

Web Security/Secure Coding

시큐어 코딩 (Open Redirect)

Open Redirect 공격이란?

 사용자로부터 입력되는 값을 외부사이트의 주소로 사용하여 자동으로 연결하는 서버 프로그램은 피싱 공격에 노출되는 취약점으로 이어질 수 있다. 일반적으로 클라이언트에서 전송된 URL 주소로 연결하기 때문에 안전하다고 생각할 수 있지만, 해당 폼의 요청을 변조함으로써 공격자는 사용자가 위험한 URL로 접속할 수 있도록 공격할 수 있다. 

 

Open Redirect 공격 원리 

1. 공격자가 URL 주소를 변조하여 배포

2. 다른 사용자가 사이트를 접속

3. 피싱 사이트 혹은 악성 다운로드 페이지로 자동 연결 

 

예를 들어, www.테스트.com 사이트에서 특정 URL로 이동시키는 작업이 파라미터에 존재할 경우, 공격자는 www.테스트.com/?url=악성주소 를 만들어 악성 주소가 포함된 URL을 배포한다. 이 때, 악성주소가 인코딩 되어 있을 수도 있으며, URL의 길이가 길 경우 사람들이 올바른 주소인 줄 착각하고 해당 URL로 접속하는 경우들이 있다. 즉, 이와 같이 Open Redirect 공격을 당하게 되면, 피싱 사이트로 리다이렉트 될 수 있으며 혹은 악성 파일이 다운로드 될 수 있다. 

 

아래 예시 코드를 보며, 어떻게 취약점이 발생하게 되는지 알아보자. 

[안전하지 않은 코드] 

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String query = request.getQueryString(); 
    if(query.contains("url")) { 
        String url = request.getParameter("url"); 
        response.sendRedirect(url); 
    }
}

위 코드를 보면, 사용자가 파라미터로 전달한 URL을 바로 리다이렉트 시키고 있다. 이러한 경우, Open redirect 공격이 발생할 수 있다. 이 공격을 막기 위해서는 화이트 리스트를 작성하여 지정된 주소가 아닐 경우 Default 로 URL 주소를 지정해주거나 오류 페이지를 띄워주면 Open Redirect 공격을 막을 수 있다.  

 

추가적으로, Open Redirect가 가능한지 테스트 해주는 자동화 툴이 존재한다. 

github.com/r0075h3ll/Oralyzer

 

GitHub - r0075h3ll/Oralyzer: Open Redirection Analyzer

Open Redirection Analyzer. Contribute to r0075h3ll/Oralyzer development by creating an account on GitHub.

github.com

Oralyzer는 여러 경우들을 테스팅하여 Open Redirect 공격이 가능한지 알려주는 자동화 툴로 취약점을 확인하는데 유용하게 활용될 수 있으니, 가이드에 따라 테스트 해보는 것도 좋을 것 같다. 

 

Open Redirect 공격 (우회)

먼저 URL 구조를 살펴보면, @ 이전을 userinfo로 @ 이후를 host로 인식한다. 

URL 구조 (출처: https://en.wikipedia.org/wiki/URL)

예를 들어, http://www.테스트.com/?url=사이트 이러한 URL이 있으면, http://www.테스트.com/?url=@공격 사이트 이와 같이 @를 사용하여 공격 사이트를 host 로 만들어 Open redirect 공격을 시도할 수도 있다. 

 

보안 방법

1. 자동 연결할 외부 사이트의 URL과 도메인은 화이트 리스트로 관리

2. 사용자 입력 값을 자동 연결할 사이트 주소로 사용하는 경우, 입력된 값이 화이트 리스트에 존재하는지 확인 

 

[안전한 코드]

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // Secure Coding (숫자 이용) 
    String allowURL[] =  {"http://url1.com", "http://url2.com", "http://url3.com"}; 
    // 입력받는 URL을 미리 정해진 URL의 순서로 받는다. (숫자 활용) 
    // www.테스트.com/?url=1
    String url = Request.getParameter("url"); 
    int nurl = Integer.parseInt(url); 
    
    try{
        if (n >= 0 && n < 3) { 
            response.sendRedirect(allowURL[n]); 
        }
    }catch (NumberFormatException nfe){ 
        // 에러 출력 
    }
}

위 코드를 보면, 숫자가 아닐 경우 에러처리를 하고 있다. 즉, 외부 주소로 Redirect 해야하는 경우 화이트 리스트를 만들어놓고 숫자로 해당 URL에 접근 가능하도록 만들어주는 것이 Open Redirect 공격을 막을 수 있는 방식임을 알 수 있었다. 

 

참고 문헌

[1] 시큐어 코딩 보안 가이드 https://www.kisa.or.kr/public/laws/laws3_View.jsp?mode=view