유형 | 입력데이터 검증 및 표현 |
보안약점 | 신뢰되지 않는 URL 주소로 자동접속 연결 |
개요 |
사용자로부터 입력되는 값을 외부 사이트의 주소로 사용하여 자동으로 연결하는 서버 프로그램은 피싱(Phishing) 공격에 노출되는 취약점을 가질 수 있다.
일반적으로 클라이언트에서 전송된 URL 주소로 연결하기 때문에 안전하다고 생각할 수 있으나, 공격자는 해당 폼의 요청을 변조함으로써 사용자가 위험한 URL로 접속할 수 있도록 공격할 수 있다.
|
보안대책 |
자동 연결할 외부 사이트의 URL과 도메인은 화이트 리스트로 관리하고, 사용자 입력값을 자동 연결할 사이트 주소로 사용하는 경우에는 입력된 값이 화이트 리스트에 존재하는지 확인해야 한다.
|
진단방법 |
외부 사이트로 리다이렉션하는 함수나 메소드(java의 경우 response.sendRedirect 메소드)가 존재하는지 확인하고, 리다이렉션 하는 함수나 메소드의 인자값(url)이 외부 입력값인지 확인한다.
일반적으로 외부에서 입력받는 변수가 아닌 경우 안전하다고 판정한다.
외부에서 입력받는 변수인 경우, 리다이렉션 하는 함수나 메소드의 인자값(url)을 관리하는지 확인해서 유효값 검사 및 화이트 리스트로 관리하는 경우 안전한 것으로 판정한다.
|
연관된 설계단계 기준 | HTTP 프로토콜 유효성 검증 |
코드예제
다음과 같은 코드가 서버에 존재할 경우 공격자는 아래와 같은 링크에 희생자가 접근하도록 함으로써 희생자가 피싱 사이트 등으로 접근하도록 할 수 있다.
<a href="http://bank.example.com/redirect?url=http://attacker.example.net">Click</a>
● 안전하지 않은 코드 예 (Java)
String id = (String) session.getValue("id");
String bn = request.getParameter("gubun");
// 외부로부터 입력받은 URL이 검증 없이 다른 사이트로 이동이 가능하여 안전하지 않다.
String rd = request.getParameter("redirect");
if (id.length() > 0) {
String sql = "select level from customer where customer_id = ? ";
conn = db.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, id);
rs = pstmt.executeQuery();
rs.next();
if ("0".equals(rs.getString(1)) && "01AD".equals(bn)) {
response.sendRedirect(rd);
return;
}
● 안전한 코드 예 (Java)
// 이동 할 수 있는 URL범위를 제한하여 피싱 사이트 등으로 이동 못하도록 한다.
String allowedUrl[] = { "/main.do", "/login.jsp", "list.do" };
......
String rd = request.getParameter("redirect");
try {
rd = allowedUrl[Integer.parseInt(rd)];
} catch(NumberFormatException e) {
return "잘못된 접근입니다.";
} catch(ArrayIndexOutOfBoundsException e) {
return "잘못된 입력입니다.";
}
if (id.length() > 0) {
......
if ("0".equals(rs.getString(1)) && "01AD".equals(bn)) {
response.sendRedirect(rd);
return;
}
● 안전하지 않은 코드 예 (C#)
// 외부 입력값으로 받은 URL 을 검증 없이 연결하고 있습니다.
string url = Request["dest"];
Response.Redirect(url);
● 안전한 코드 예 (C#)
public void AttackOpenRedirect()
{
string url = Request["dest"];
// 외부 입력값이 로컬 URL인지 확인합니다. MVC 3 이상의 프레임워크를 사용할 경우,
// System.Web.Mvc 에 정의되어있는 Url.isLocalUrl 을 바로 사용할 수 있습니다.
if(isLocalUri(url)) Response.Redirect(url);
}
private bool IsLocalUrl(string url)
{
if(string.IsNullOrEmpty(url))
{
return false;
}
Uri absoluteUri;
if(Uri.TryCreate(url, UriKind.Absolute, out absoluteUri))
{
return String.Equals(this.Request.Url.Host, absoluteUri.Host, StringComparison.OrdinalIgnoreCase);
}
else
{
bool isLocal = !url.StartsWith("http:",StringComparison.OrdinalIgnoreCase)
&& !url.StartsWith("https:", StringComparison.OrdinalIgnoreCase)
&& Uri.IsWellFormedUriString(url, UriKind.Relative);
return isLocal;
}
}
진단방법

외부 사이트로 리다이렉션하는 함수나 메소드(java의 경우 response.sendRedirect 메소드)가 존재하는지 확인하고(①), 리다이렉션 하는 함수나 메소드의 인자값(url)이 외부 입력값인지 확인한다(②).
일반적으로 외부에서 입력받는 변수가 아닌 경우 안전하다고 판정한다.
외부에서 입력받는 변수인 경우, 리다이렉션 하는 함수나 메소드의 인자값(url)을 관리하는지 확인해서 유효값 검사 및 화이트 리스트로 관리하는 경우 안전한 것으로 판정한다.
● 일반적인 진단의 예
public class U601 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String query = request.getQueryString(); ·······································②
if(query.contains("url")) {
String url = request.getParameter("url");
// url에 대한 유효성 점검없이 sendRedirect의 인자로 사용
if(url != null) {
url = url.replaceAll("\r","").replaceAll("\n","");
response.sendRedirect(url); ············································①
}
}
}
}
외부 입력값을 이용하여 URL을 이동하는 response.sendRedirect(String url) 함수가 사용된다면 취약하다.
● 정탐코드
<%
//redirect
String code = nvl(request.getAttribute("redirectCode"));
String action = nvl(request.getAttribute("action"));
logger.debug(">>> redirectCode - " + code);
logger.debug(">>> redirectAction - " + action);
………
se.sendRedirect(CP + action + "?redirectCode=" + code);
return;
%>
code, action을 request에서 받아온다. 이후 페이지 이동 URL에 code, action 값을 사용하여 URL을 만든다.
● 오탐코드
response.sendRedirect(request.getContextPath() + "/login.do");
HttpRequest.getContextPath() 함수는 내장함수로 context path를 리턴하므로 안전한 URL이다.
'소프트웨어(SW) 보안약점 진단원 > 구현단계 보안약점 제거 기준' 카테고리의 다른 글
구현단계 보안약점 기준 - XML 삽입 (0) | 2025.05.26 |
---|---|
구현단계 보안약점 기준 - 부적절한 XML 외부개체 참조 (1) | 2025.05.26 |
구현단계 보안약점 기준 - 위험한 형식 파일 업로드 (0) | 2025.05.26 |
구현단계 보안약점 기준 - 운영체제 명령어 삽입 (2) | 2025.05.21 |
구현단계 보안약점 기준 - 크로스사이트 스크립트 (1) | 2025.05.15 |