JSP 보안 개발 가이드

1절. 보안 대책

1. 스크립트 삽입 취약점

가. 취약점 상세 내용 및 보안 대책

Javascript, Vbscript 등 PC의 웹브라우저에서 실행되는 클라이언트 사이트 스크립트를 다른 사용자의 웹브라우저에서 실행하도록 함으로서 웹 브라우저를 제어하여 PC를 공격하는 취약점을 말한다. 공격에 사용되는 유형은 크게 두가지로 분류할 수 있다.

(1) Reflected XSS

이 유형의 XSS는 클라이언트 측에서 전송된 데이터가 서버측에서 즉시 처리된 후 사용자에게 응답으로 전송되는 돌아오는 경우에 해당한다. 다음과 같은 상황에서 발생이 가능하다.

  1. 검색 페이지에서 입력된 검색어가 검색 결과 페이지에 표시되는 경우
  2. URL에 포함된 특정 파라미터가 응답 페이지에 hidden 속성으로 포함되어 있는 경우

위의 두가지 유형은 본질적으로는 동일한 내용이다.
이러한 유형의 XSS 는 사회 공학적 방법 등을 통해서 공격 스크립트가 포함된 URL을 타인이 실행하도록 유도함으로서 (예를 들면 메신저로 링크를 전송하거나, 게시판에 URL을 링크로 걸어놓고 클릭을 유도하는 방식 등) 공격에 이용될 수 있다. 다만, 공격자가 강제적으로 타 사용자의 PC에서 공격 스크립트가 실행되도록 할 수는 없으므로 일반적으로 심각한 취약점으로 분류되지는 않는다.
그러나 공공기관이나 금융권과 같이 신뢰도가 중요한 대상인 경우에는 이 유형의 XSS 도 모두 제거해야 하며, 그 외에도 대외에 공개된 웹사이트라면 일반적으로 제거하도록 하는 것이 좋다.

(2) Stored XSS

게시판과 같이 사용자가 입력한 정보가 서버측 DB에 저장되어 있다가 타 사용자가 해당 정보를 열람할 때 DB에 저장되어 있는 정보를 가져와 화면에 출력하는 방식의 웹 애플리케이션에서 발생하는 취약점으로서, XSS의 가장 핵심적인 취약점이라고 할 수 있다. 불특정 다수를 대상으로 열람자의 웹브라우저에서 공격 스크립트를 실행할 수 있기 때문에 심각한 위협이 발생한다.
공격자가 XSS를 목적으로 악성 스크립트를 삽입하여 둘 수 있는 위치는 비단 게시판의 글 본문 뿐만 아니라 제목, 작성자 이름, 날짜, 첨부파일 이름 등이 모두 가능하며, 또한 게시판 외에도 사용자 프로필의 닉네임, 주소, 전화번호, 등 사용자가 입력이 가능한 모든 데이터에 스크립트가 삽입될 수 있다.

  • 게시판 : 제목, 본문, 작성자, 날짜, 첨부파일 이름, 태그, 분류 등
  • 사용자 프로필 : 이름, 닉네임, 주소, 전화번호, 이메일, 직업, 기타 입력정보
  • 기타 사용자가 입력 가능한 모든 데이터

나. 보안 대책

XSS에 대한 보안 대책은 적용할 대상에 따라 다음의 두가지 경우를 나누어 적용해야 한다. 먼저 태그를 사용할 필요가 없는 경우와 태그의 사용을 허용해야 하는 경우이다.

  • 태그를 사용할 필요가 없는 경우
    사내 게시판이나 reflected XSS의 경우와 같이 문자열 내에 HTML 태그를 허용할 필요가 없는 경우
  • 태그를 사용해야 하는 경우
    대외 고객용 게시판, 커뮤니티 게시판 등과 같이 사용자의 필요에 의해서 문자열 내에 태그를 사용해야만 하는 경우
(1) 태그를 허용할 필요가 없는 경우 (사내 게시판, Reflected XSS)

태그를 허용할 필요가 없는 사내 게시판 등 단순 게시판의 경우는 사용자가 입력하는 모든 데이터에서 <, > 문자를 HTML Special Character 로 인코딩 함으로서 XSS를 완전히 차단할 수 있다. HTML Special Character 로 인코딩 된 코드는 웹브라우저에서 화면에 출력될 때는 정상적인 문자열로 출력되지만, 태그나 스크립트로서는 작동하지 않기때문에 XSS 로부터 안전하게 된다.

인코딩 대상 문자 HTML Special Character 코드
< &lt;
> &gt;


Reflected XSS 는 화면에 표시되는 모든 변수값들 (hidden field 포함)에 대해서 발생 가능하므로 모든 출력값에 대한 검증이 수행되어야 한다.

JSP

따로 제공하는 인코딩 함수가 없으므로 직접 replace 문을 통해 <, > 를 필터링하는 함수를 작성하여 사용한다.

resultStr = resultStr.replaceAll("<", "&lt;");
resultStr = resultStr.replaceAll(">", "&gt;");

한편, jsp 에서는 프리젠테이션 페이지를 작성할 때, JSTL 을 사용하면 모든 출력값이 자동으로 인코딩되므로 따로 replace를 할 필요가 없으므로 편리할 수 있다. (개발 단계라면 권고할 만 함)

<c:out value="${value}" />
(2) 태그를 허용해야 하는 경우 (공개 게시판)
게시판의 태그 허용에 대한 대응

공개 게시판과 같은 커뮤니케이션 중심의 웹 애플리케이션에서는 사용자들이 게시물을 꾸미거나 링크, 이미지, 동영상 등의 사용을 원하기 때문에 HTML 태그를 완전히 금지할 수 없다. 따라서 <, >를 필터링하되, 사용자가 사용해야하는 태그에 대해서는 <, > 를 필터링해서는 안된다.
따라서 웹사이트 운영자는 자신의 게시판에서 사용자에게 허가할 최소한의 HTML 태그를 선별한 후, 각각의 태그들에 대해서만 역변환 (즉, &lt;, &gt; 등으로 replace 된 <, >를 다시 원래대로 되돌리는 것)해야 한다.
또한 해당 태그들을 허용할 경우 발생 가능한 위협들에 대해서 대처하기 위한 별도의 방어 코드를 추가로 작성해야 한다. 방어 코드는 다음의 두 가지 방식을 적용할 수 있다.

가. 단어 blacklist 를 필터링 하는 방식

이 방식은 XSS 공격에 자주 사용되는 단어를 필터링하여 사용할 수 없도록 하는 방식이다
이 방식은 구현하기가 간단하지만, blacklist에 포함되지 않는 코드가 공격에 사용될 경우 막을 수 없으며, 또한 필터링 우회 기법이 발전함에 따라 필터링 자체가 우회될 가능성이 있다. 또한 blacklist로 선정된 단어를 사용자가 게시물에 사용할 수 없다는 단점이 있다.

blacklist 코드 예
// blacklist 를 필터링하여 사용할 수 없도록 함
test_str_low= test_str.toLowerCase();
test_str = test_str_low;
test_str = test_str.replaceAll("javascript", "x-javascript");
test_str = test_str.replaceAll("script", "x-script");
test_str = test_str.replaceAll("iframe", "x-iframe");
test_str = test_str.replaceAll("document", "x-document");
test_str = test_str.replaceAll("vbscript", "x-vbscript");
test_str = test_str.replaceAll("applet", "x-applet");
test_str = test_str.replaceAll("embed", "x-embed");  // embed 태그를 사용하지 않을 경우만
test_str = test_str.replaceAll("object", "x-object");    // object 태그를 사용하지 않을 경우만
test_str = test_str.replaceAll("frame", "x-frame");
test_str = test_str.replaceAll("grameset", "x-grameset");
test_str = test_str.replaceAll("layer", "x-layer");
test_str = test_str.replaceAll("bgsound", "x-bgsound");
test_str = test_str.replaceAll("alert", "x-alert");
test_str = test_str.replaceAll("onblur", "x-onblur");
test_str = test_str.replaceAll("onchange", "x-onchange");
test_str = test_str.replaceAll("onclick", "x-onclick");
test_str = test_str.replaceAll("ondblclick","x-ondblclick");
test_str = test_str.replaceAll("enerror", "x-enerror");
test_str = test_str.replaceAll("onfocus", "x-onfocus");
test_str = test_str.replaceAll("onload", "x-onload");
test_str = test_str.replaceAll("onmouse", "x-onmouse");
test_str = test_str.replaceAll("onscroll", "x-onscroll");
test_str = test_str.replaceAll("onsubmit", "x-onsubmit");
test_str = test_str.replaceAll("onunload", "x-onunload");
}
나. 태그의 property를 검증하는 방식

사용을 허가할 각각의 태그들에 대해서 property 들에 대해 개별적으로 유효성 검사를 실시하여 정상적이지 않은 방식으로 사용된 property를 걸러내는 방식이다. 이 방식은 구현하기가 좀더 복잡하지만 허가되지 않은 모든 형태의 입력을 거부하는 방식이므로 우회될 가능성이 낮아 보다 안전하며, 필터링이 사용자의 게시물의 내용을 손상시키지 않는 장점이 있다.
예를 들면 <img> 태그에 대해 다음과 같은 규칙을 적용하여 규칙이 위반된 property는 모두 삭제하는 방식이다.

img 태그의 허가 규칙
- img 태그는 property에 src, width, height 만 허용(그 외의 모든 property 는 무시)
- src 는 http://- 로 시작하는 이미지 파일 경로만 허용 (확장자로 . jpg .gif 등만 허용)
- width, height 의 값은 숫자만 허용

이 방식의 대책을 적용하기 위해서 고려해야 할 요소들은 다음과 같다.

  • 최소한의 HTML 태그만 허용한다
  • 각 태그별로 필수적인 프라퍼티만 허용한다
  • onClick, onerror 등 이벤트 유형의 프라퍼티는 허용하지 않는다
  • 각 프라퍼티에 삽입되는 데이터의 형식을 엄격하게 제한한다. (예 : “src” 프라퍼티에 URL 주소만 입력 가능해야 하며 “javascript:alert(‘test’);” 등과 같은 내용이 입력되어서는 안됨)

새로운 HTML 규약의 개발, 웹브라우저의 발전 등으로 인해 XSS 공격 패턴은 계속 새로운 패턴이 개발될 것이기 때문에, XSS 에 대한 필터링 로직 역시 지속적으로 테스트되고 수정되어야 할 필요가 있다.

2. SQL Injection 취약점

가. 취약점 상세 내용 및 보안 대책

웹 사이트는 DBMS와 연동하므로 웹 어플리케이션에서 사용자의 입력값을 통하여 데이타 트랜잭션이 발생함. 만일 사용자 입력값에 대한 유효성 검증이 누락될 경우, 악의적인 사용자는 정상적인 입력값 대신 SQL 쿼리문이 포함된 조작된 입력값을 전송하여 서버측 쿼리문의 구조를 변경할 수 있으며, 이를 통해서 사용자 인증을 우회하거나 데이터베이스의 정보를 유출시키고 서버의 시스템 명령어를 실행시킬 수도 있음.

나. 보안 대책

(1) Database 운영 레벨에서 SQL Injection 방어 대책

DB 또는 웹사이트 운영자가 SQL Injection을 방어하기 위해서는 기본적으로 다음과 같은 사항에 유의하여 관리가 필요하다.

  • DB 계정에 최소 권한 부여
    • 웹사이트에서 사용되는 DB 계정에 최소한의 권한만 부여해야 함
    • DB 계정에 system 권한 (sysdba, sa, root 등)을 부여해서는 안됨
  • 에러 노출 방지
    • 에러 발생시 웹서버 또는 WAS 에서 정형화된 에러 페이지를 출력하도록 설정하여 에러에 의한 DB 정보 노출을 방지함
  • SQL Server의 경우 xp_cmdshell 확장 프로시저를 제거함

그러나 위와 같은 방법만으로는 SQL Injection을 방어할 수 없으므로 다음과 같이 소스코드 레벨에서 취약점을 제거하기 위한 대책을 적용해야 한다.

(2) 소스코드 레벨에서 Prepared Statement 구문을 통한 SQL Injection 방어

웹사이트가 개발중에 있다면 DAO 객체 또는 DB 연결 구문에서 Prepared Statement 구문을 이용하여 DB 트랜잭션을 처리함으로서 SQL Injection 취약점이 근본적으로 발생하지 않는 구조로 웹사이트를 개발해야한다.
Prepared Statement 구문은 SQL 쿼리를 선처리하여 컴파일 한 후, 이후 입력되는 변수값을 항상 문자열 변수로 다루기 때문에 사용자가 어떤 악의적인 SQL 구문을 변수에 삽입해도 SQL 문에 영향을 미치지 않아 SQL Injection이 발생하지 않는다.

JSP 에서 Prepared Statement 구문 사용

Jsp 에서 prepared Statement 구문을 구성하는 간단한 예시는 다음과 같다.

prepared Statement 구문
// 객체 선언
Connection con;
PreparedStatement pstmt;
ResultSet rs;

// DB연결 생성
con = DriverManager.getConnection(-------);

// Query 문 및 변수값 세팅
pstmt = con.prepareStatement(“Select  name, id, num from Membertable where id=? And passwd=?“);
pstmt.setString(1, "test");             // 변수형에 따라 setXXXX 사용 ex) setInt, setDouble
pstmt.setString(2, "testpwd");

// Query 문 실행
rs = pstmt.executeQuery();          // executeQuery, executeUpdate

// 결과 처리
if (rs.next()){
	// rs 객체로부터 칼럼 이름을 이용한 결과값 추출하여 사용자 펑션의 실행
	Run_user_function (…, rs.getString(name), rs.getString(id), rs.getint(num));
	// 또는 인덱스를 이용한 결과값 추출
	Run_user_function (…, rs.getString(1), rs.getString(2), rs.getint(3));

}

// 객체 close
rs.close();
pstmt.close();

※ 참고 : 저장 프로시저를 이용하여 DB 트랜잭션을 처리하는 방법 역시 prepared statement 구문과 동일한 효과를 기대할 수 있다.

(3) 소스코드 레벨에서 필터링 코드를 통한 SQL Injection 방어

만일 이미 운영중인 웹사이트에서 DB 트랜잭션 처리를 Prepared Statement 구문으로 수정하는 것이 어려울 경우, 차선책으로 특수 문자 및 Query 문자열에 대한 필터링을 통해서 SQL Injection 이 발생하지 않도록 해야 한다.
사용자측으로부터 전달되는 파라메터 중 DB 쿼리문에 사용되는 모든 파라미터 (게시판 ID, 글 번호, 검색 keyword, 사용자 번호, 항목 번호, 분류명칭 등)로부터 입력되는 데이터에 대하여 아래와 같이 특수 문자 및 Query 예약어를 필터링해 에러 처리를 하거나 ‘\’ 문자 또는 공백 문자로 치환한다.

필터링 할 특수 문자 및 구문
' union
select
insert
# drop
( update
) from
; where
@ join
= substr (oracle)
* user_tables (oracle)
/ user_table_columns (oracle)
+ subsring (ms-sql)
information_schema (mysql) sysobjects (ms-sql)
table_schema (mysql) declare (ms-sql)
JSP 에서 필터링 샘플 코드
필터링 샘플 코드
// 특수문자 필터링을 위해 특수문자를 정의
Pattern evilChars = Pattern.compile("['\"\\-#()@;=*/+]");
// 특수문자는 모드 공백으로 치환
test_str = evilChars.matcher(test_str).replaceAll("");

// 특수 구문 필터링 (데이터베이스가 Oracle 인 경우)
test_str_low= test_str.toLowerCase();
if(test_str_low.contains("union") || test_str_low.contains("select") || test_str_low.contains("insert") || test_str_low.contains("drop") || test_str_low.contains("update") || test_str_low.contains("delete") || test_str_low.contains("join") || test_str_low.contains("from") || test_str_low.contains("where") || test_str_low.contains("substr") || test_str_low.contains("user_tables") || test_str_low.contains("user_tab_columns"))
{
test_str = test_str_low;
test_str = test_str.replaceAll("union", "q-union");
test_str = test_str.replaceAll("select", "q-select");
test_str = test_str.replaceAll("insert", "q-insert");
test_str = test_str.replaceAll("drop", "q-drop");
test_str = test_str.replaceAll("update", "q-update");
test_str = test_str.replaceAll("delete", "q-delete");
test_str = test_str.replaceAll("and", "q-and");
test_str = test_str.replaceAll("or", "q-or");
test_str = test_str.replaceAll("join", "q-join");
test_str = test_str.replaceAll("substr", "q-substr");
test_str = test_str.replaceAll("from", "q-from");
test_str = test_str.replaceAll("where", "q-where");
test_str = test_str.replaceAll("declare", "q-declare");
test_str = test_str.replaceAll("openrowset", "q-openrowset");
test_str = test_str.replaceAll("user_tables","q-user_tables");
test_str = test_str.replaceAll("user_tab_columns","q-user_tab_columns");
test_str = test_str.replaceAll("table_name","q-table_name");
test_str = test_str.replaceAll("column_name","q-column_name");
test_str = test_str.replaceAll("row_num","q-row_num");
}

3. 파일 업로드

가. 취약점 상세 내용 및 보안 대책

첨부 파일 업로드 기능이 있는 게시판 등에서 실행 가능한 확장자를 가진 스크립트 파일의 업로드가 허용되는 경우, 공격자에 의해 악성 프로그램이 업로드 되어 실행 될 수 있음.
공격자는 첨부한 악성 프로그램을 실행하여 웹 서버 사용자 권한 획득한 후 내부 네트워크로의 침입을 시도하거나 DB 에 연결하여 중요 정보를 유출시킬 수 있음.

나. 보안 대책

(1) 서버 운영 관점의 보안 대책

서버 운영 관점에서 아래와 같은 대책을 적용함으로서 소스코드 상의 취약점에 의해서 악성 파일이 업로드 되더라도 공격자가 이를 실행할 수 없도록 함으로서 업로드 취약점에 의한 피해를 최소화 해야 한다.

  • 파일이 업로드 되는 디렉토리의 스크립트 실행 권한을 제거함
  • 업로드 디렉토리를 서버측 디렉토리 구조에서 웹루트 디렉토리 (예: Apache 의 DocumentRoot)의 서브 트리 바깥에 위치시킴으로서 사용자측 웹브라우저에서 URL을 통해서 업로드 디렉토리에 직접 접근할 수 없도록 구성
(2) 소스코드 관점의 보안 대책

웹 애플리케이션의 소스코드에서 아래와 같이 실행 가능한 파일들이 서버에 업로드 할 수 없도록 필터링하여 제한하는 모듈을 추가해야 한다.

ASP .asa, .asp, .cdx, .cer, .htr, .aspx
JSP .jsp, .jspx
PHP .html, .htm, .php, .php3, .php4, .php5

위의 표에서 제시된 확장자 목록들은 일반적인 설정 환경에 해당되는 목록이지만, 각 서버측 스크립트 엔진에서 실행 가능한 것으로 인식하는 확장자의 종류는 각각의 서버측 설정에 따라 다르다. 따라서 만일 별도로 등록한 실행 가능 확장자가 있다면 제한 목록에 추가해야 한다.
한편, 실제로 필터링 로직을 구현할 때, black list 방식의 필터링 (제한할 목록 외에는 모두 허용하는 방식) 으로 구현할 경우, 제한할 keyword의 누락 가능성이 존재하고 또한 문자열 인코딩 등을 통해서 필터링의 우회가 가능할 수 있기 때문에 일반적으로 더 안전한 white list 방식의 필터링이 권장된다.
white list 방식의 필터링은 허용할 확장자 목록(예: .jpg, .doc, .xls 등) 만을 확정 선정하고 그 외의 모든 확장자를 제한하는 방식의 필터링이다.

확장자 필터링 로직은 일반적으로 다음과 같은 원칙에 따라 구현되어야 한다.

  • 필터링은 반드시 Server Side 에서 구현해야 함
  • 파일의 확장자 검사를 할 때 문자열을 이용한 trick에 의해서 필터링이 우회되지 않도록 신중하게 구현해야 함
    • 대소문자 구분없이 비교 또는 Lower case 로 일괄 변경하여 비교 (test.JsP, test.jsP 등)
    • 파일명의 가장 우측에 있는 확장자를 비교함으로서 “test.gif.jsp”, “test.jsp.”, “test.jsp;test.jpg” 등의 방식으로 필터링이 우회되지 않도록 구현
  • 업로드되는 파일을 저장할 때, 파일명과 확장자를 추측할 수 없는 무작위 문자열 및 실행 불가능한 확장자로 변경하여 저장함. (권장 사항)
  • 저장 경로 및 파일명은 DB에 저장한 후, index 번호를 통해서 호출하도록 함으로써 파일명 및 경로를 외부에 노출되지 않도록 함. (권장 사항)

위에서 마지막 두가지 적용 항목은 구현시 복잡한 로직의 변경이 요구되므로 이미 운영되고 있는 서버의 경우 필수적인 항목은 아니다. 그러나 금융권과 같이 완벽한 보안을 추구해야만 하는 곳이거나 개발 단계에서 보안이 고려되는 경우는 위의 두가지 로직을 적용하도록 권고해야 한다.

JSP 에서 소스 코드 보안 대책
  • 파일 확장자 추출 코드 예시
파일 확장자 추출 코드 예시
<%
   String filePath = "/test/test.jsp";
String fileExt = filePath.substring(filePath.lastIndexOf('.') + 1).toLowerCase();
%>
  • Black List 방식의 필터링 코드 예시
    Windows 서버에서 동작하는 JSP의 경우는 ”;(세미콜론)” 파싱 관련 취약점이 발생할 수 있으며 Black List 방식의 필터링의 경우는 “.(dot)” 관련 문제점이 발생할 수 있으므로 이에 대한 처리 코드를 포함해야 한다. (Unix에서 동작하는 Jsp는 관련 없음)
Black List 방식의 필터링 코드 예시
<%

Boolean checkResult = true;

// 업로드 금지 확장자 리스트
String blockExt[] = {"jsp","jspx"};

// 금지할 확장자 체크
for(int i=0; i<blockExt.length;i++) {
if( blockExt[i].equals(fileExt) ){
checkResult = false;
break;
    }
}

// Windows일 경우 (.) 및 세미콜론 파싱 오류 관련 처리
if(fileExt.length() == 0 ) {
checkResult = false;
}
if(filePath.contains(";")) {
checkResult = false;
}

if(checkResult == false){
out.println ("업로드가 금지된 파일 입니다.");
}else{
out.println ("업로드가 허용된 파일 입니다.");
}

%>
  • White List 방식 필터링 코드 예시
    Windows 서버에서 동작하는 JSP의 경우는 ”;(세미콜론)” 파싱 관련 취약점이 발생할 수 있으므로 이에 대한 처리 코드를 포함해야 한다. (Unix에서 동작하는 Jsp는 관련 없음)
White List 방식 필터링 코드 예시
<%

Boolean checkResult = false;

// 업로드 허용 확장자 리스트
String allowExt[] = {"doc","docx","xls","xlsx","jpg","gif","txt"};

// 허용할 확장자 체크
for(int i=0; i<allowExt.length;i++) {
if( allowExt[i].equals(fileExt) ){
checkResult = true;
break;
    }
}

// Windows일 경우 세미콜론 파싱 오류 관련 처리
if(filePath.contains(";")) {
checkResult = false;
}

if(checkResult == false){
out.println ("업로드가 금지된 파일 입니다.");
}else{
out.println ("업로드가 허용된 파일 입니다.");
}

4. 파일 다운로드

가. 취약점 상세 내용 및 보안 대책

Web Application 의 download 관련 모듈의 파라미터에 path traversal 문자열을 삽입하여 웹 루트 디렉토리의 상위 경로에 위치하는 OS파일 시스템까지 접근할 수 있으며, 이를 이용해서 시스템의 각종 중요 파일 및 웹 프로그램의 소스 코드를 다운로드할 수 있음.

나. 보안 대책

파일 다운로드 취약점으로부터 안전하기 위해서는 다운로드 모듈을 다음과 같이 구현하도록 일반적으로 권고된다.

  • 파일 다운로드 모듈 구현시 실제 파일 경로는 DB에 저장하도록 하고 사용자에게 노출되는 URL의 파라미터에는 인덱스 번호를 통해 다운로드 할 파일을 표시함으로서 사용자에게 조작을 시도할 수 있는 경로 정보가 노출되지 않도록 구현함

그러나 위의 방식으로 구현하기 위해서는 웹사이트 로직을 수정하는 데 다소 복잡한 작업이 필요하다. 따라서 공공기관이나 은행권 사이트와 같이 정보 노출에 매우 민감한 사이트를 제외한 내부 직원용 포털 등의 사이트에서는 차선책으로서 다음과 같은 필터링 코드를 적용하여 취약점을 해결하도록 한다.

  • 파일 다운로드 모듈 구현시 파일 경로를 처리하는 파라미터 변수에서 디렉토리 상위 경로를 의미하는 path traversal 문자열을 필터링하여 사용할 수 없도록 함
    (필터링할 문자열 : [..], [../], [..\],)
  • 다운로드를 허용할 디렉토리를 지정하여 해당 디렉토리를 벗어나는 위치의 다운로드 요청에 대해서는 경고메시지와 함께 다운로드를 금지하도록 함
JSP 에서 필터링 코드의 구현 예시
필터링 코드의 구현 예시
<%
// 다운로드 허용할 디렉토리 설정
String allowPath = "/server/upfiles/";

// 파라미터로부터 다운로드할 파일을 입력 받아 전체 경로를 생성함
String inputPath = getParameter("downfile");
String filePath = allowPath + inputPath;

// 금지 문자열 리스트
String blockchar[] = {"..", "../", "..\\"};

Boolean checkResult = true;

// 금지할 문자열 포함 여부 체크
for(int i=0; i<blockchar.length;i++) {
if( filePath.indexOf(blockchar[i]) != -1 ){
checkResult = false;
}
}

// 파일 전체 경로로부터 디렉토리 경로만 추출한 후, 다운로드 허용된 디렉토리인지 체크
String path = filePath.substring (0, filePath.lastIndexOf("/") + 1).toLowerCase();
if( !path.equals(allowPath) ){
    checkResult = false;
   }

if(checkResult == false){
out.println ("다운로드가 금지된 파일 입니다.");
}else{
out.println ("다운로드가 허용된 파일 입니다.");
}

%>

5. URL 강제 접속 / 인증 우회

가. 취약점 상세 내용 및 보안 대책

모든 웹페이지는 개별적으로 인증 및 권한 관리 모듈을 포함하고 있어야 한다. 그렇지 않을 경우 인증받지 않은 사용자가 해당 페이지의 URL 을 직접 입력하여 강제 접속할 수 있다.
또한 인증 및 권한 모듈은 반드시 안전한 방식으로 구현되어야 하며, 만일 인증 및 권한 관리 로직이 취약하여 우회가 가능하거나 권한 관리가 제대로 이루어지지 않는 경우, 불법적인 접근이나 허가받지 않은 Role 의 허용으로 중요 정보의 유출, 서비스의 무단 사용 등 심각한 문제가 발생할 수 있다.

나. 보안 대책

URL 강제 접속 또는 인증 우회 취약점은 웹사이트의 인증 및 권한 관리 모듈의 취약점으로 인해 발생하게 된다.
이를 해결하기 위해서는 웹사이트의 모든 페이지에 대해서 개별적으로 적절한 인증 및 권한 검증이 수행되어야 하므로 일반적으로 인증 및 권한 관리를 담당하는 공통 모듈을 작성하여 각 페이지에 삽입하는 방식으로 구현하는 경우가 많다.
인증 및 권한 관리 모듈에서 발생하는 취약점의 주요 원인은 다음과 같다.

  • 인증 및 권한 관리 모듈이 존재하나 특정 페이지에 누락되어 있는 경우
  • 인증 및 권한 관리 모듈의 구현에 취약점이 존재하여 이에 대한 우회가 가능한 경우
(1) 특정 페이지에 인증 및 권한 관리 모듈이 누락된 경우

인증 및 권한 관리 모듈이 이미 존재하지만 특정 페이지에만 해당 모듈의 적용이 누락된 경우는 공통 모듈을 페이지에 추가하는 것으로 해결할 수 있다.
그러나 이러한 유형의 취약점은 여러 페이지에서 복수로 발견되는 경우가 일반적이기 때문에 취약점 진단(또는 모의해킹)에서 모든 페이지에 대한 전수 검사를 진행하지 않은 이상은 공통 인증 모듈이 누락된 페이지들 중에서 아직 발견되지 않은 경우가 존재할 가능성이 높다.
따라서 웹사이트 운영자 담당자 또는 유지보수 개발사는 이 취약점을 해결할 때 취약점이 보고된 특정 위치 뿐만 아니라 웹사이트의 모든 페이지에 대해서 검토를 실시할 것을 권고한다. 각각의 페이지에 대해서 다음 사항을 검토하도록 한다.

  • 이 페이지는 접근시 인증이 필요한 페이지 인가?
  • 이 페이지에 접근하는 모든 유저에 대해서 인증 및 권한이 적절하게 검사되고 있는가?
(2) 인증 및 권한 관리 모듈에 취약점이 발생하여 우회가 가능한 경우

인증 및 권한 관리 모듈의 취약점은 각 사이트마다 다양한 형태가 나타나지만 일반적으로 다음과 같은 사항들에 유의하여 모듈을 설계 및 수정함으로서 취약점을 보완하도록 한다.

  • 인증 및 권한의 허용의 초기값은 default 로 모든 경우에 deny 로 설정 후, 필요한 권한을 부여받은 유저에 대해서만 해당 권한을 allow 하는 방식으로 구현함
  • Role based 권한 관리를 구현할 때, 접근 권한이 없는 메뉴나 링크를 단순히 화면에 표시하지 않는 방식으로만 구현한 후, 각 페이지의 권한 검증을 누락하게 되면 URL 강제 접속에 취약하게됨. 메뉴나 링크를 화면에 표시하지 않는 것과는 별도로 반드시 모든 페이지에서 권한을 검증해야 함
  • 특정 권한이 요구되는 작업이 일련의 flow를 통해서 수행되는 경우, 해당 flow의 중간 단계를 포함한 모든 작업 단계에 대해서 인증 및 권한 검증이 이루어져야 함 (예 : 게시판의 글 수정은 form 페이지에서 내용을 입력받은 후 action 페이지에서 데이터 업데이트를 처리하고 view 화면으로 전환하는 flow로 이루어 지는데, form, action, view 페이지에서 모두 인증 및 권한 검증이 별도로 이루어져야 함)
  • 권한 없는 페이지에 대한 접근 시도가 발생했을 때 “location.href=’/error/accessDeny.jsp’” 와 같은 형태로 javascript에 의해 페이지를 Redirection 처리 하는 방식으로 구현하는 경우, Redirection 스크립트 코드가 실행되는 페이지는 접근이 거부된 페이지의 정상적인 내용을 포함해서는 안됨

가. 취약점 상세 내용 및 보안 대책

Cookie는 HTTP 프로토콜의 비연결성 특징을 고려하여 사용자 Session 관리의 편의성을 도모하기 위해 사용되는 기술적 방법이며, 주로 웹사이트의 설정값을 저장하여 각 사용자가 웹사이트에 접속할 때 동일한 설정을 유지하거나 또는 사용자의 인증과 관련된 정보를 처리하기 위해 사용된다.
그러나 Cookie 근본적으로 Client Side Session 기술로서 전달되는 값에 대한 사용자의 조작이 가능한 문제가 있기 때문에 Cookie 의 변수에 중요한 정보를 포함하여 사용하는 경우 Client 측 웹브라우저의 조작을 통해서 해당 값을 변조하여 인증을 우회하거나 타 사용자의 정보를 도용하는 등의 취약점이 발생할 수 있다.
또한 Cookie 로 전달되는 변수는 GET / POST 를 통해서 전달되는 변수와 동일하게 SQL Injection 및 파라미터 조작 등의 공격에 영향을 받을 수 있다.

나. 보안 대책

(1) Session 방식의 사용

평문 정보를 Cookie 변수에 저장하여 서버와 클라이언트 간에 전달하는 일반적인 방식의 Cookie 활용은 더 이상 권장되지 않는다.
WAS와 같은 서버측 스크립트 엔진은 Cookie 보다 발전된 형태인 Session 방식의 상태값 전달 방식을 지원한다. Session 방식은 서버측의 저장 공간에 각 사용자별로 인증 정보나 설정값 등 특화된 정보를 저장할 수 있는 저장소를 지원하며 암호화된 Cookie 변수를 통해 이를 식별하게 하는 방식으로 이루어져 있으므로 Client 측에서 정보의 변조가 불가능하며, 따라서 Cookie 방식보다 안전하다.
따라서 인증이나 권한 정보와 같이 변조되어서는 안되는 중요한 정보는 가능한 Session 방식을 이용하여 구현하는 것이 바람직하다.

만일 Cookie 변수에 데이터를 저장하여 전송할 필요가 있는 경우, 해당 정보가 인증 및 권한 등 중요한 정보일 경우 평문으로 사용해서는 안되며 반드시 SEED, 3DES, AES등 공인된 암호화 알고리즘을 사용하여 정보를 암호화한 후 사용해야 한다.
또한, 중요한 정보가 아니라고 해도, Cookie 변수를 통해서 전달되는 변수값은 GET/POST 파라미터 변수와 마찬가지로 SQL Injection, XSS, 파라미터 조작 등과 같은 공격에 영향을 받기 때문에 각각의 취약점을 방어하기 위한 적절한 입력값 검증이 수행되어야 한다.

  • Cookie 변수로 전달된 값이 DB와 연동하는 로직으로 전달되어 사용되는 경우 반드시 SQL Injection 공격을 차단하기 위한 대응책을 적용해야 함
  • Cookie 로 전달되는 변수가 장바구니, 결재 모듈 등 웹사이트의 중요한 로직에서 사용되는 경우, 변수의 변조 가능성에 대비한 적절한 유효성 검증이 수행되어야 함

7. URL 파라미터 조작

가. 취약점 상세 내용 및 보안 대책

공격자는 웹 URL의 GET/POST 파리미터 또는 HTML 코드의 <INPUT> 변수, Hidden field, javascript 변수 등에서 노출되는 데이터를 통해서 서버측 프로그램의 로직 및 역할 등을 유추할 수 있다. 또한 해당 변수의 값을 고의적을 변조하여 특정한 값을 입력하여 전송하므로서 서버측 프로그램이 자신이 원하는 특정 작업을 수행하도록 조작을 시도할 수 있다.
만일 웹사이트 로직이 신중하계 설계되지 않는다면 공격자가 전송한 조작된 입력값에 의해서 서버측 프로그램이 의도되지 않은 오동작이나 정상적인 처리 범위를 벗어난 불법적인 작업이 발생할 수 있다.
웹사이트의 유형이나 제공하는 기능에 따라서 파라미터 변조를 통해 발생할 수 있는 위협의 종류는 매우 다양하다. 일반적으로 발생 빈도가 높은 취약점 유형들을 정리하면 다음과 같다

  • 게시물 번호 조작을 통한 타 사용자의 게시물에 대한 무단 열람/수정/삭제
  • Role based 웹사이트에서 사용자 Role 등급의 임의 변경
  • 온라인 결재시 상품 금액 등 결재 데이터의 변조
  • 아이디, 사번 등의 변조를 통해 타 사용자 정보의 무단 열람 및 수정
  • 회원 가입시 실명 인증에 대한 우회
  • 접근이 제한되어 있는 정보에 대한 무단 열람 또는 변조
  • 인증 로직의 우회, 악성 파일의 업로드, 서버측 리소스에 대한 무단 다운로드

나. 보안 대책

파라미터 변수의 변조를 통한 공격을 방어하기 위해서는 Client 측에서 전송되어온 정보가 변조되었을 가능성이 있다는 것을 항상 고려하여 서버측 프로그램을 설계해야 한다. 예를 들면 GET/POST 변수, Cookie변수, HTTP Header, Referer 등 Client 에서 전송되어 온 대부분의 데이터가 변조될 수 있다.
따라서 이와 같은 데이터 변조에 대비하기 위해서는 웹사이트에서 인증, 결재, 정보의 열람 및 수정 등 중요한 작업을 설계할 때 다음과 같은 사항에 유의하여 신중하게 로직을 설계해야 한다.

  • 중요한 작업 수행시 Session 객체에 저장된 정보와 같이 Client 측에서 조작할 수 없는 신뢰할 수 있는 정보에 기반하여 적절한 권한을 가진 사용자에 의해 작업이 요청되었는 지를 반드시 검증해야 함
  • 여러 단계의 flow를 거쳐 수행되는 작업의 경우, flow의 시작과 끝 단계에서 작업에 사용된 변수들을 서로 비교 검증함으로서 중간 단계에서 특정 변수가 변조되지 않았는지 여부를 검사함 (예: 회 가입을 처리할 때 처음 단계에서 실명 인증이 통과된 성명/주민등록번호가 중간 단계를 거치는 동안 변조되었는지 여부를 마지막 저장 단계에서 검증해야 함)
  • 중요한 작업의 기준이 되는 정보 (예: 결재 모듈에서 상품의 가격 정보, 회원정보 수정시 사용자의 ID 정보 등)는 GET/POST 파라미터 등으로부터 입력 받은 변수값의 사용을 자제하고 Session 객체나 DB 와 같이 신뢰할 수 있는 저장소의 정보를 읽어와 사용하도록 함 (예를 들면 상품의 가격 정보는 DB에서 읽어오도록 하고, 사용자의 ID 는 Session 객체에서 읽어오도록 함)

이 유형의 취약점은 진단 대상의 구조 및 종류, 서비스 유형 등에 따라서 다양한 형태로 발생하게 되므로 각 진단대상의 특성과 로직을 분석하여 대상에 맞는 적절한 보안 대책을 적용해야 한다.

8. 취약한 ID/PW

가. 취약점 상세 내용 및 보안 대책

로그인 인증을 통과해야만 접근할 수 있는 웹페이지의 경우, 취약한 계정을 사용한다면, 공격자는 해당 웹사이트의 정보를 바탕으로 자주 사용되는 word를 이용한 사전 파일 공격을 시도하거나, 또는 무작위 대입 방식에 의해서 취약한 계정을 획득할 수 있음.
시스템에서 기본으로 제공하는 계정이나 DBMS, 어플리케이션 서버 등에서 관리를 위해 제공하는 기본 계정을 그대로 사용하는 경우 공격자에게 쉽게 계정의 사용 여부가 노출될 수 있음. 일반 사용자 계정 역시 여러 가지 방법으로 공격자에게 계정의 존재 여부가 노출될 수 있음.

나. 보안 대책

사용자가 취약한 패스워드를 사용할 수 없도록 패스워드 생성 규칙을 선정하고 이에 대한 안내 및 강제할 수 있는 로직을 적용해야 함.

  • 패스워드 생성 규칙 예시
    • admin, master 등 유추하기 쉬운 계정 이름 사용 금지
    • 8자 이상 숫자, 영문자, 특수문자를 혼합하여 패스워드를 생성해야 함
    • 자신과 관련된 정보를 이용한 패스워드 생성 금지(계정과 유사 한 패스워드 등)
    • 간단한 문자(영어단어 포함)나 숫자의 연속사용은 금함
    • 사전에 있는 단어, 이를 거꾸로 철자화한 단어 또는 숫자 하나를 더한 단어 사용 금지
    • 기억하기 쉽게 만들어 별도의 기록이 필요 없도록 함
    • 키보드상에서 일련화된 배열을 따르는 패스워드 선택 금지
    • 패스워드를 주기적으로 변경해야 함
    • 패스워드의 최소 사용기간, 최대 사용기간을 설정함
    • 이전에 사용한 패스워드는 재 사용 금지

9. 디렉터리 인덱싱

가. 취약점 상세 내용 및 보안 대책

웹서버 설정상의 오류나 개발 과정의 편의를 위해서 웹 디렉토리 내부의 파일 리스트가 웹브라우져를 통해서 출력되도록 설정되어 있을 수 있음
웹 디렉토리의 파일 목록이 노출되면 공격자에게 웹사이트 구조 및 환경과 관련된 정보가 노출될 수 있으며, 백업 파일이나 설정 파일 등이 웹 디렉토리 내부에 존재할 경우, 공격자가 이 파일을 다운로드하여 웹사이트의 핵심적인 정보를 획득할 수 있음

나. 보안 대책

사용중인 웹서버를 확인한 후, 설정 파일 또는 관리 콘솔상에서 Directory Indexing 을 허용하지 않는 것으로 변경함.

  • Apache
    DocumentRoot 디렉터리 내의 모든 파일의 목록이 출력되는 것을 방지하기 위해서 httpd.conf 파일 내의 <Directory> 설정 영역에서 “Options” 지시자 에서 “Indexes” 옵션을 제거한다.
    DocumentRoot 디렉토리의 최상위 디렉토리에서 Indexes 옵션을 제거하면 하위 디렉토리에도 모두 적용되지만 특정 하위 디렉토리에서 Indexes 옵션이 추가되어 있을 경우, 하위 디렉토리의 설정이 우선 적용되므로 하위 디렉토리의 모든 Indexes 옵션도 제거하도록 한다.
<Directory “/usr/local/www”>
    Options Indexes FollowSymLinks     (---> Indexes 지시어 삭제)
    AllowOverride None
</Directroy>
  • IIS
    인터넷 정보서비스(IIS) 관리 –> [해당 웹사이트] → [등록정보] → [홈 디렉토리] → [디렉토리 검색] 체크박스를 해제한다.

  • WebTob
    환경파일내의 ‘DIRINDEX’절 삽입유무 확인 후, ‘NODE’절의 ‘NODE’절에 ‘DIRINDEX’절과 관계된 설정을 확인한다. ‘DIRINDEX’절을 삽입하지 않거나 Options 값을 ‘-index’로 설정함
    (※ 환경파일 : ${WEBTOBDIR}/config/[파일명.m] )
*NODE
nex-edfa87d356c	WEBTOBDIR="C:/TmaxSoft/WebtoB4.1", 
		SHMKEY = 54000,
		DOCROOT="C:/TmaxSoft/WebtoB4.1/docs",
		PORT = "8080", 
		HTH = 1,
		LOGGING = "log1",
		ERRORLOG = "log2",
		JSVPORT = 9900,
		DirIndex = "diridx_full",
		Options = "-index"

*DIRINDEX
diridx_full	Options = "Fancy"

10. 디폴트 페이지

가. 취약점 상세 내용 및 보안 대책

웹서버, WAS 등 플랫폼을 디폴트 옵션으로 설치할 경우, 사용자의 편의를 위해 제공되는 각종 예제 및 샘플 페이지, 설치 정보, 관리 콘솔 등이 함께 설치된다. 이런 기능들은 제품별로 항상 동일한 경로에 설치되는 것이 일반적이며, 설치 정보가 일반에 공개되어 있기 때문에 공격자들의 주요 공격 목표가 될 수 있으며, 특히 샘플 페이지 등에 존재하는 취약점이 공격의 경로로 이용된 사례가 과거에 보고되어 있다.
따라서 샘플 페이지 등이 관리되지 않고 방치되는 경우 보안 취약점으로 작용할 가능성이 있는 만큼 사용하지 않는 기능은 설치하지 않거나 삭제하는 것이 바람직하며, 만일 사용되어야 하는 기능들은 철저한 관리를 통해 사고를 방지해야 한다.

나. 보안 대책

운영중인 웹서버에서 사용하고 있는 웹서버, WAS, Database, 기타 Third party 제품군을 파악하고 각 제품별로 디폴트로 설치되는 기능들 중에서 불필요한 기능이 있는지 검토하여 삭제하도록 한다.

  • 불필요한 샘플 페이지 및 기능의 삭제
    • 웹 서버/WAS의 Default Page와 Banner를 삭제
    • PHP의 phpinfo 페이지 삭제
    • WAS 등의 사용 예제 및 샘플 도메인 삭제
    • Tomcat, Jeus, IIS, Weblogic 등의 관리 콘솔 중 사용하지 않는 기능을 중지하거나 삭제
    • 기타 Third party 제품군의 관리 페이지, 샘플 페이지 등을 삭제
  • 디폴트 페이지 사용시 관리 강화
    • 디폴트 페이지나 관리 콘솔을 사용해야 하는 경우, 접근 경로 및 접근 port 의 디폴트 설정값을 변경하여 사용하도록 함
    • 관리 콘솔 설치시 생성되는 디폴트 계정은 사용하지 않도록 하고 별도의 계정을 생성하여 사용함
    • 관리 콘솔 등 중요한 기능의 경우 적절한 ACL 정책을 적용함
    • Third party 제품군의 관리 페이지 등이 일반에 노출되지 않도록 주의함

11. 백업 파일

가. 취약점 상세 내용 및 보안 대책

웹 디렉토리 내에 백업용 압축파일, 테스트 파일 등이 존재하고 유추 가능한 이름으로 되어 있는 경우, 별도의 과정 없이 다운로드가 가능하거나 내용이 브라우저 상으로 출력될 수 있으므로 이를 통해서 중요한 정보가 노출될 위협이 있음.

나. 보안 대책

아래의 내용을 확인하고 해당 사항이 발견될 경우, 적절한 조치를 취애햐 함.

  • 관리자는 웹 디렉토리를 조사하여 *.asp.bak , *.jsp.bak, *.php.old와 같은 백업파일을 모두 삭제 해야 함.
  • *.txt 같은 웹 페이지의 작업 도중 생성된 일반 텍스트 파일이나 그 밖에 이미지 파일 등도 본래 파일 이외에는 제거하여야 하며 *.asp.bak, *.jsp.bak 파일 이외의 *.bak 파일도 불필요한 경우는 삭제해야 함.
  • 백업 파일 같은 경우 언제 생성될 지 관리자의 측면에서는 알기가 매우 힘드므로 cron등을 이용하여 주기적으로 검사 및 삭제할 것을 권고하며 가급적이면 웹 서버를 실행하는데 필요한 파일을 제외하고는 모두 삭제할 것을 권고함.

12. 에러 페이지 미비

가. 취약점 상세 내용 및 보안 대책

공격자가 대상 시스템의 현황을 파악하기 위하여 다양한 에러를 유발시킴으로써 반응하는 에러 결과값으로 웹 프로그램의 구조 및 환경설정을 추측하여 공격에 이용되므로 이러한 Error를 위한 별도의 페이지를 작성하여 Error발생시 기본 Error Page로 Redirect 시킴으로써, 불필요한 정보가 노출되지 않도록 해야 함. SQL Injection 공격으로 대상시스템의 SQL Query문장의 구성을 알아내기 위한 Foot Printing 시도와 같은 것이 이 항목에 해당됨

나. 보안 대책

모든 에러(404 error,403 error,500 error, …)발생 시 에러 메시지를 외부에 제공하지 않도록 함. 에러가 발생한 경우 에러 발생 메시지를 사용자 클라이언트의 브라우저에 표시하지 않게 하고 메인 페이지 또는 별도로 만든 에러 페이지로 Redirect 시키도록 함.

  • Apache 에러페이지 설정
Apache 에러페이지 설정
# 사용자 정의 에러 반응 메시지 (아파치 스타일)
# 다음 3 가지 방법으로 가능함.
#
# 1) 보통의 텍스트
#ErrorDocument 500 "The server made a boo boo.
# 주목: " 표시는 텍스트임을 알려주는 것으로서 그 자체는 출력되지 않음.
#
# 2) 지역적인 방향 전환
#ErrorDocument 404 /missing.html
# 지역적 URL인 /missing.html로 방향 전환하기
#ErrorDocument 404 /cgi-bin/missing_handler.pl
# 주목: 스크립트나 SSI로 방향 전환시킬 수 있음.
#
# 3) 외부 방향 전환
#ErrorDocument 402 http://some.othercom.com/subscription.html
# 주목: 원래 요청과 관련있는 환경 변수의 상당수가 스크립트에 전달되지 못함.
내부 방향 전환에는 전혀 이상이 없으나 외부 방향 전환 시 가끔 에러가 발생 함.
ErrorDocument 400 /message/400error.html
ErrorDocument 401 /message/401error.html
ErrorDocument 403 /message/403error.html
ErrorDocument 404 /message/404error.html
ErrorDocument 405 /message/405error.html
ErrorDocument 500 /message/500error.html
ErrorDocument 501 /message/501error.html
또는 스크립트를 이용하여 변수를 전달시킬수도 있음.
ErrorDocument 400 /message/error.php?ecode=400
ErrorDocument 401 /message/error.php?ecode=401
ErrorDocument 403 /message/error.php?ecode=403
ErrorDocument 404 /message/error.php?ecode=404
ErrorDocument 405 /message/error.php?ecode=405
ErrorDocument 500 /message/error.php?ecode=500
ErrorDocument 501 /message/error.php?ecode=501
  • IIS 에러페이지 설정
    인터넷 정보서비스(IIS) 관리 – [속성] – [사용자 지정 오류] 탭에서 아래와 같이 에러표시 페이지를 설정한다.

13. 중요정보 전송구간 암호화

가. 취약점 상세 내용 및 보안 대책

인터넷 구간을 통해서 계정 정보나 사용자 정보를 전송할 때 SSL이나 암호화가 적용되지 않은 상태로 전송된다면, 공격자는 인접 네트워크 대역이나 무선 LAN 환경에서 네트워크 트래픽을 모니터링 함으로서 전송되는 정보들을 수집하여 계정 정보나 개인 정보 등 중요 정보를 획득할 수 있다.
만일 암호화나 SSL 이 적용되어 있는 경우에도 안전한 것으로 공인된 강력한 알고리듬이 사용되지 않았거나 SSL 환경 및 인증서 설정의 오류로 인해 취약점이 발생할 수 있다.
또한 많은 웹사이트에서는 퍼포먼스의 문제로 인해서 민감한 정보를 다루는 일부 페이지에서만 SSL 및 암호화를 적용하는데, 민감한 데이터를 전송하면서도 SSL 및 암호화의 적용이 누락되는 페이지가 존재하는 경우가 많기 때문에 보다 철저한 점검이 요구된다.

나. 보안 대책

인터넷 전송 구간을 안전하게 방어하기 위한 가장 쉬운 대책은 웹사이트 전체에 SSL 또는 암호화를 적용하는 것이다. 그러나 퍼포먼스의 문제로 인해서 대부분의 경우 민감한 정보를 다루는 페이지에만 암호화 및 SSL을 적용하게 된다.
웹사이트에서 암호화 및 SSL을 적용할 때는 최소한 다음의 원칙을 준수해야 한다.

  • 민감한 데이터를 다루는 모든 페이지에 적용하고 누락되는 페이지가 없도록 확인
  • GET/POST와 같은 Request 데이터 뿐만 아니라 Response 데이터의 HTML 코드에 포함된 <INPUT>변수 또는 javascript 변수 등도 민감 정보가 포함되어 있을 수 있다는 점에 유의하여 이에 대한 암호화가 누락되지 않도록 함
  • SSL 적용시 인증서를 정확하게 설정하여 사용자의 웹브라우저에서 인증서 경고창이 출력되지 않도록 주의 함 (웹을 사용하기 위해 사용자가 인증서 경고창을 무시하고 진행하도록 강요하는 상황은 해당 사이트 유저의 Fishing 공격에 대한 대응을 약화시켜 Fishing 위협을 증가시키는 결과를 초래함)
  • SSL 이 필요한 웹페이지에 대해서 일반 HTTP로 요청할 경우 반드시 SSL 페이지로 리다이렉트 시키도록 함
  • 로그인시 계정 정보를 단순 인코딩 또는 해쉬값을 이용하는 경우 복호화 없이도 해당 정보를 로그인 인증을 통과하기 위한 인증 값으로 이용할 수 있으므로 대칭키/비대칭키를 이용한 적절한 암호화가 실시되어야 함

14. 사용자 정보 및 기타 중요 정보 노출

가. 취약점 상세 내용 및 보안 대책

웹사이트를 통해서 발생하는 사용자 개인정보 및 중요 정보의 노출은 그 발생 원인이 매우 다양하다. 예를 들면 웹사이트 운영상의 단순한 실수로 정보가 노출되는 경우도 있고, 또는 웹사이트의 설정상의 오류나 보안 취약점에 대한 공격의 결과로서 정보가 노출되는 유형도 존재할 수 있다.
웹사이트 운영상의 실수로 정보가 노출되는 대표적인 유형을 살펴보면, 관리되지 않고 방치되는 게시판 또는 삭제되지 않은 구 버전 웹사이트, 백업 파일 관리 미흡, 관리자의 실수로 업로드된 엑셀 파일 또는 게시물, 비공개 게시물이 설정 실수로 인해 전원에게 공개되는 경우 등을 들 수 있다.
또한 웹사이트 설정 오류나 보안 취약점에 의해 발생하는 유형으로는 암호화가 미흡하거나 파일 업로드 취약점이나 파일 다운로드 취약점을 통해 서버측의 리소스가 직접 유출되는 경우, 디렉토리 인덱싱에 의해 파일 목록이 유출되는 경우, 파라미터 변조 취약점 등에 의해서 발생하는 경우, SQL Injection 등을 통해 DB 데이터가 직접 유출되는 경우도 존재할 수 있다.
따라서 이를 해결하기 위해서는 운영 담당자의 상시 웹사이트 점검 노력과 보안 취약점의 제거 대책이 종합적으로 적용되어야 할 것이다.

나. 보안 대책

웹사이트 운영 담당자는 다음과 같은 내용을 상시 점검해야 한다.

  • 공지사항에 올린 게시물에 개인정보가 포함되어 있지 않은가?
  • 게시판에 업로드한 첨부 파일에 개인정보가 포함되어 있지 않은가?
  • 웹사이트 리뉴얼 후 구버전 웹사이트가 계속 접속 가능한 상태로 방치되어 있지 않은가?
  • 웹사이트에 관리되지 않는 불필요한 포트가 허용되어 있지 않은가? (예: 80 포트와 8080 포트를 동시 허용된 상태로 8080포트에 웹방화벽이나 SSL 적용이 이루어지지 않는 경우)
  • 공개/비공게 게시판 또는 서비스에 대한 접근 Role 설정이 적절하게 관리되고 있는가?
  • 웹 방화벽이나 SSL 적용이 누락된 페이지가 존재하지 않는가?

또한 사회 공학적 유형의 정보 유출이 발생하지 않도록 다음과 같은 정책의 적용해야 한다.

  • 주민등록번호, 비밀번호와 같은 민감한 정보 입력시 화면상에 ‘*’로 처리한다.
  • 관리자 페이지 등을 통해 사이트 운영자가 회원들의 개인정보에 무단으로 접근하여 열람하지 못하도록 대책을 강구한다.
  • 민감한 정보에 대한 접근은 로그를 기록하고 규정에 따라 보관하도록 한다.

15. 관리자 페이지 접근

가. 취약점 상세 내용 및 보안 대책

관리자 기능이 일반 사용자 기능과 분리되어있지 않을 경우, 해당 기능의 경로가 노출되기 쉬우며, 노출된 경로를 통해서 일반 사용자의 접근 시도가 발생하거나 또는 악의적인 공격자에 의한 계속적인 공격을 유발할 수 있음.
관리자 페이지는 적절한 접근 통제가 이루어져야 하며, 접근 통제 없이 임의의 위치에서 접근 가능할 경우, 해당 경로를 유추하거나 기타 다양한 방법에 의해서 위치가 노출될 수 있으므로 이를 통해서 악의적인 공격자에 의한 brute force 공격 등이 발생할 수 있음.

나. 보안 대책

관리자 페이지는 다음과 같은 보안 정책에 의해서 보호되어야함.

  • 관리자 페이지는 일반 사용자용 인터페이스와 분리되어 작성되어야 함. (별도의 포트, 도메인 등)
  • 관리자 페이지는 임의의 위치에서 접근할 수 없도록 적절한 접근 통제 절차가 적용되어야 함 (IP 접근 제어, SMS 인증 등)
  • 추측하기 쉬운 디렉터리명이나 파일명을 사용해서는 안됨.
추측가능한 관리자 페이지 예
http://www.abc.com/admin.html
http://www.abc.com/admin_main.html
http://www.abc.com/admin/index.html
http://www.abc.com/admin/login.html
http://www.abc.com/master.html
http://www.abc.com/master/index.html

16. WebDAV 취약점

가. 취약점 상세 내용 및 보안 대책

윈도우 서버 컴퓨터에서 기본으로 설치되는 원격관리기능인 WebDAV가 계속 사용가능하도록 설정되어 있고, WebDAV 라이브러리 파일의 속성 및 홈페이지 디렉토리에 쓰기 권한이 모두 허용되어 있는 경우에 해커가 WebDAV 도구를 사용, 원격에서 홈페이지 디렉토리에 임의의 파일을 삽입하여 화면을 변조할 수 있다.

나. 보안 대책

만약 원격 웹 서버 관리를 하지 않는다면 반드시 웹데브 기능을 중지시켜야 한다. 웹데브는 앞서 설명한 취약점 외에도 버퍼오버플로 취약점 등이 존재하여 단지 웹데브 기능이 ‘사용가능’ 상태로 되어 있는 것만으로도 문제가 될 수 있다.

(1) IIS 를 사용하지 않을 경우
  • [시작]-[프로그램]-[관리 도구]-[컴퓨터 관리]-[서비스 및 응용 프로그램]-[서비스] > [World Wide Web Publishing Service] 속성 - [일반] > 서비스 중지 및 시작유형을 사용 안함으로 설정
(2) IIS 를 사용하는 경우
  • 레지스트리 편집기(Regedt32.exe)에서 다음 키를 찾아 값을 수정하거나 추가함
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W3SVC\Parameters
값 이름: DisableWebDAV
데이터 형식: DWORD
값 데이터: 1
  • IIS 6.0 이상에서는 다음과 같이 인터넷정보서비스 관리에서 WebDAV 항목을 중지함

17. 검색 엔진 중요정보 노출

가. 취약점 상세 내용 및 보안 대책

Google 같은 검색엔진의 검색 결과는 해당 검색 엔진의 데이터베이스에 저장되거 유지되기 때문에 중요 정보가 검색 엔진의 검색 결과에 일단 노출이 되면 자신의 웹사이트에서 해당 정보를 삭제해도 검색엔진의 검색 결과에는 일정 기간 정보가 계속 남아있어 유출이 계속 발생하게 된다.
따라서 중요한 정보는 반드시 인증을 거쳐아먄 접근할 수 있는 페이지에 게시하여 검색엔진에 의해서 임의로 정보가 유출되지 않도록 주의해야 하며, 노출된 것으로 확인된 정보는 해당 검색엔진에 직접 정보를 삭제해줄 것을 요구해야 한다.
또한 주기적으로 웹사이트의 URL 및 중요정보의 keyword를 조합하여 검색엔진의 검색 결과를 점검해보고 노출되어서는 안되는 정보가 검색엔진에 노출되어 있는지 여부를 확인하도록 한다.
노출되기 원하지 않는 정보에 대해서는 robots.txt 파일을 설정을 통해 검색을 거부하도록 한다.

나. 보안 대책

(1) 검색엔진에 노출된 중요 정보의 삭제

검색 엔진에 중요 정보가 노출되어 있을 경우, 자신의 웹사이트에서 정보를 삭제해도 검색엔진에는 일정기간 동안 검색 결과가 유지되므로 해당 검색엔진에 내용의 삭제를 직접 요구하도록 한다.

(2) 검색엔진에 의한 검색을 방지하기 위한 설정
* robots.txt 설정

Google, Naver, Daum 등 대부분의 검색엔진은 robots.txt 파일에 의한 검색 거부 규약을 지키고 있으므로 규약에 맞게 robots.txt 파일을 작성하여 적용하면 검색엔진에 노출되는 것을 원치 않는 URL에 대해서 검색을 거부할 수 있다.
robots.txt 작성 방법은 아래와 같다.

모든 검색엔진이 자신의 웹사이트 검색을 금지함
User-agent: *
Disallow: /
모든 검색엔진에게 자신의 특정 디렉토리에 대한 검색을 금지함
User-agent: *
Disallow: /my_directory1/
Disallow: /my_directory2/my_directory3
특정 검색엔진이 자신의 웹사이트를 검색하는 것을 금지함
User-agent: Googlebot
Disallow: /

robots.txt 작성할 때는 다음 사향에 주의하도록 한다.

  • robots.txt 파일은 웹 URL의 최상위 디렉토리에 위치해야 함
  • robots.txt 에서 디렉토리 경로는 URL에서 도메인 주소를 뺀 나머지 디렉토리 트리 구조로 표현함
  • robots.txt 파일은 텍스트 파일로서 누구나 URL을 통해서 열람이 가능한 파일이므로 관리자 페이지경로와 같은 민감한 경로는 포함해서는 안됨
* 메타 태그 설정 (특정 페이지에 대한 검색 거부)

메타 태그를 이용하면 특정 페이지에 대한 정보 수집을 거부할 수 있다. 메타 태그를 사용하기 위해서는HTML의 <head> 태그 사이에 다음 구문을 삽입한다.

<meta name="robots" content="noindex, nofollow">
Google 에서 검색결과 테스트

자신의 사이트의 주요 정보가 검색엔진에 노출되어있는지 테스트하기 위해서 다음과 같은 유형의 검색 keyword를 통해서 주기적으로 검색 결과를 점검하도록 한다.

Google 검색 키워드 예시
- inurl:www.myweb.co.kr filetype:doc
- inurl:www.myweb.co.kr 고객명단
- inurl:www.myweb.co.kr admin

18. 특수 문자 취약점

가. 취약점 상세 내용 및 보안 대책

웹서버 및 WAS는 제품과 버전에 따라 ‘Null’, ‘%00’, ‘%3f’, ‘#’, ‘::’ 등과 같은 특수 문자의 처리시 발생하는 버그로 인해 요청된 URL 의 소스 코드를 노출시키거나 디렉토리 목록 등을 출력하는 문제가 과거 여러 차례 보고된 바 있다.
따라서 웹사이트 운영 담당자는 담당 웹사이트에서 사용하고 있는 제품의 Vendor에서 제공하는 패치 정보 및 보안 권고문을 항상 확인하도록 하고, 보안 이슈 사항에 대해서 자신의 서버가 영향이 있는지를 테스트하여 적절한 보안 대책을 적용하도록 한다.
또한 자신이 운영하고 있는 웹사이트가 과거에 발생했던 특수 문자 처리 취약점의 영향을 받고 있는지를 테스트하여 만일 취약점을 갖고 있다면 이를 즉시 해결해야 한다.

나. 보안 대책

아래 사항을 점검 후, 취약한 것으로 확인된 경우는 자신의 Vendor 사의 보안 권고문을 확인하고 지시에따라 보안 패치를 설치하거나 웹서버 또는 WAS의 설정을 변경한다.

* Resin 2.x 이전 버전 / 기타 java 기반 웹 애플리케이션 서버 공통

아래와 같이 입력시 디렉토리 목록을 출력

* JEUS

아래와 같이 입력시 요청 URL의 소스코드 또는 디렉토리 목록을 출력

아래와 같이 입력시 URL의 소스코드를 출력

* 플랫폼 공통

다음과 같은 특수문자가 삽입된 URL 을 테스트하여 웹서버의 반응을 확인한 후, 정상적인 400, 403, 404, 500 error가 아닌 특수한 반응(예: 소스코드 출력 또는 디렉토리 목록 출력)이 발생하는 경우, Vendor사의 보안 권고문에서 해당 내용을 검색하여 지시에 따라 대책을 적용해야 한다.

테스트할 특수문자 목록
테스트할 특수문자 목록 : [.], [%2E], [+], [%2B], [%2A], [\], [%5C], [?], [%3F], [%20], [%00]

테스트할 URL 패턴은 다음의 두가지 케이스를 테스트한다. (예: %2E를 테스트 할 경우)