본문 바로가기

JAVA

[JAVA] Secure 코딩, 취약점 해결, 보안을 위한 방법 정리

프로젝트를 진행하면 반드시 시큐어코딩을 점검하게 됩니다. 대부분 툴로 돌리기 때문에 오탐도 많이 나오긴 하지만 일단 기본적인 보안 취약점 요소와 해결방안을 간략하게라도 알고 코딩하는게 좋습니다. 

 

JAVA 프로젝트에서 보안은 항상 중요합니다.

Unreleased Resource

Abstract :

프로그램이 시스템 리소스를 해제하지 못할 수도 있음

 

Explanation :

전반적인 소프트웨어 안정성 문제를 일으키지만 공격자가 의도적으로 리소스 누출을 일으킬 수 있는 경우

리소스 풀을 고갈시켜 denial of service 공격을 일으킬 수도 있습니다.

 

Recommendation :

개체를 사용해서 처리하는 동안 예외가 발생하면 close() 등의 자원반납 메서드가 실행이 안될 수 있다.

따라서 예외발생시에도 자원반납이 이루어지도록 try catch를 사용해야 한다.

Statement stmt;
try{
 stmt = conn.createStatement();
 ResultSet rs = stmt.executeQuery();
} finally {
 safeColse(stmt);
}

//공통메서드를 정의해서 null체크, try, catch, log 기록 등을 쉽게 하도록 한다.
public static void safeClose(Statement stmt){
 if(stmt!=null){
  try{
   stmt.close();
  }catch(SQLException e){
   log(e);
  }
 }
}

 

자원반납이란 해당객체를 null로 만들어서 가비지컬렉터에 의해 해제가 되는 것이다.

파일 I/O 관련된 소스에서

FileInputStream fs = new FileInputStream(File);

BufferedInputStream in = new BufferedInputStream(fs);

in.close()를 하게 되면 in = null; 로 세팅해서 참조를 해제, 가비지컬렉터에 의해 자원반납이 이루어지도록 하는 것이다.

이 때 보조스트림의 close()를 사용하면 자동으로 기반스트림의 close()를 호출하게 되므로 fs를 별도로 안닫아줘도 된다.

 

Cross-Site Scripting(XSS) 

Abstract :

검증되지 않은 데이터를 웹 브라우저에 보내면 브라우저에서 악성 코드를 실행하는 결과를 초래할 수 있음

 

Explanation :

웹 브라우저에 전달되는 악성코드는 흔히 JavaScript 세그먼트의 형태를 취하지만 HTML, Flash 또는 기타 브라우저가 실행할 수 있는 유형의 코드를 포함할 수도 있음.

XSS 취약점은 HTTP 응답에 확인되지 않은 데이터가 포함된 코드(자바스크립트 등) 때문에 발생함.

 

Recommendation :

응용프로그램에 들어가거나 응용프로그램에서 사용자에게 전달되는 모든 입력을 확인하는 것이다.

가장 안전한 XSS검증방법은 HTTP컨텐트에 사용할 수 있는 안전한 문자의 화이트리스트를 만들어 이 문자 집합의 문자만으로 이루어진 입력만 받는 것이다. 그러나 많은 제약으로 인해 다양한 문자를 입력해야 할 경우 실효성이 떨어짐

안전성이 떨어지지만 유연성이 높은 블랙리스트 방식을 사용한다. 입력을 사용하기 전에 위험한 문자를 선별적으로 거부하거나 이스케이프 처리한다.

고려해야할 특수문자 <, &, >, ", ', 공백, 탭, %

% 기호는 HTTP이스케이프 시퀀스로 인코딩된 매개 변수가 서버 쪽 코드로 디코딩되는 경우 입력에서 필터링해야 함.

(%68%65%6C%6C%6F"와 같은 입력이 해당 웹 페이지에 나타날 때 "hello"가 되는 경우 필터링해야 합니다.)

 

고려해해야할 특수문자가 입력값으로 넘어오면 인코딩하여 특수한 의미를 제거해야 함.

(ISO 8859 -1 특수문자의 인코딩된 값의 완전한 목록이 공식 HTML 규격의 일부로 제공됨)

 

어떻게 해야 일괄적으로 특수문자를 인코딩할 수 있을까?

1) Filter 시스템을 이용해서 request를 통해 넘어오는 모든 입력값 안에 있는 특수문자를 인코딩하도록 한다.

   Web.xml에서 *.do에 Filter를 거는 것!

   SpecialCharFilter.java extends Filter.java

   doFilter(req, res)

   Enumeration e = req.getParameterNames();

 get방식 형태로 데이터를 연결한다.

 연결한 파라미터 안에 변경하려는 특수문자가 있는지 확인한다.

 

 변경할 특수문자가 있을 경우

 ServletRequest req = new RequestWrapper(HttpServletRequest);  

 RequestWrapper extends HttpServletRequestWrapper

 override
 getParamValues()
 
 override
 getParameter()

 

 위 두 메서드에서 파라미터값을 반환할 때 특수문자를 변경해서 반환한다.

 별도 메서드 만들어서 제공

 파라미터 각 열의 문자를 배열화해서 하나씩 접근. 문자가 변경하려는 특수문자이면 변경한 값을 stringbuffer에 변경한 값을 추가한다.

 StringBuffer sb
 for (char c : param.toCharArray()){
  switch(c){
   case '<' : sb.append(&#60;);
   case '>' : sb.append(&#62;);
  }
 }

 return sb.toString;

 

스프링의 <form: 태그를 사용하면 자동으로 인코딩 해주므로 모든 입력폼에서 <form: 태그를 사용한다.

 

클라이언트에서 모든 입력값에 대해 특수문자, 길이 등에 대한 validation한다.

필터링 조치 대상 입력값

   <SCRIPT, <OBJECT, <APPLET, <EMBED, <FORM, <IFRAME, <FRAME,

   <LAYER, <LINK, <STYLE, …

   < → &lt, > → &gt, ( → &#40, ) → &#41, # → &#35, & → &#38, …

   기타 변환문자: '&' → '&amp;', ' ' ' → '&apos;', ' " ' → '&quot;')

 

XSS Filter를 이용한다.(http://josephoconnell.com/java/xss-html-filter/ 에서 제공)

주요소스 

private String filter(String input){

 String clean = new HTMLInputFilter().filter(input);
 return clean;
}

 

OSWASP에서 제공하는 보안 API 사용

(https://www.owasp.org/index.php/Esapi)

사용예 : String safeEid = ESAPI.encoder().encodeForHTMLAttribute(name);

 

 

Code Correctness

Abstract

문자열은 == 또는 !=이 아닌 equals()메서드로 비교해야 함

 

Explanation

== 또는 != 연산자는 두 개체의 값이 아닌 참조를 비교하기 때문에 두 참조가 같지 않을 가능성이 큼

 

Recommendation

equals()메서드를 사용!!

 

 

System Information Leak

Abstract

시스템 데이터 또는 디버깅 정보가 노출되면 공격자가 시스템을 파악하고 공격계획을 세우는 것이 수월해집니다.

 

Explanation

정보누출은 시스템 데이터 또는 디버깅 정보가 출력 스트림이나 로깅 함수를 통해 프로그램을 벗어날 때 발생함

즉, Exception처리시 stackTrace(), printStackTrace 등 사용시 시스템 정보 유출될 수 있음

 

Recommendation

관리자와 프로그래머가 문제를 진단하는데 도움이 되는 상세한 출력의 생성 및 저장은 삼가는 것이 좋다.

에러발생시에는 에러 페이징 처리해야 하며,(web.xml에서 설정) Logger를 사용한다.

 

 

Header Manipulation

Abstract

HTTP 응답 헤더에 확인되지 않은 데이터를 포함하면 캐시 감염, cross-site scripting, 교차사용자변조(cross-user defacement) 또는

페이지 하이재킹(page hijacking) 쿠키 조작 또는 open redirection 공격을 유발할 수 있음

 

Explanation

데이터가 신뢰할 수 없는 소스, 주로 HTTP요청을 통해 응용프로그램에 들어갈 때 데이터는 확인작업을 거치지 않고 웹 사용자가에 전달된 HTTP 응답헤더에 포함될 때 발생한다

가장 일반적인 공경 중 하나는 HTTP Response Splitting로 해당 익스플로이트가 성공하려면 응용프로그램은 헤더에 CR(캐리지 리턴, %0d 또는 \r) 및 LF(줄바꿈, %0a 또는 \n)으로도 표시) 문자가 있는 입력을 허용해야 함

(사용자가 "Wiley Hacker\r\nHTTP/1.1 200 OK\r\n..." 와 같은 악성 문자열 전송시 HTTP 응답이 제대로 이루어지지 않음)

 

  • 교차 사용자 변조(cross-user defacement) : 공격자는 피해 서버에 하나의 요청을 보내 서버가 두 개의 응답을 만들게 하는데 두 번째 응답은 다른 요청에 대한 응답으로 잘못 해석될 수 있음
  • 캐시감염(cache - poisoning) : 여러 사용자가 사용하는 웹 캐시 또는 단일 사용자의 브라우저 캐시에서 악의적인 목적으로 생성된 읍답을 캐시하는 경우 그 영향 확대됨. 프록시 서버에서 흔히 볼 수 있는 것과 같이 공유 웹 캐시에 응답이 캐시되는 경우 해당 캐시의 모든 사용자가 캐시 항목이 없어질 때까지 악성 콘텐트를 계속 받음
  • 페이지 하이재킹(page hijacking) : 취약한 응용 프로그램을 사용하여 악성 콘텐트를 사용자에게 보내는 것 외에 같은 취약점을 이용하여 서버가 사용자에게 보내기 위해 생성한 민감한 콘텐트를 공격자에게 리디렉션할 수도 있음. 이로 인해 공격자가 서버에 두번째 요청을 보내면 프록시 서버가 피해자에게 보내기 위해 서버가 생성해 놓은 요청으로 응답함. 따라서 피해자가 수신해야할 응답의 헤더와 본문에 있는 민감한 정보가 누출 됨
  • 쿠키조작 : Cross - Site Request Forgery와 같은 공격과 결합된 경우, 공격자는 올바른 사용자의 쿠키를 변경하고 해당 쿠키에 추가하거나 쿠키를 덮어쓰기도 할 수 있음
  • Open Redirection : 리디렉션에 사용된 URL을 제어하는데 확인되지 않은 입력을 사용하면 피싱 공격을 도울 수 있음

 

Recommedation :

응용 프로그램의 기존 입력값 검증 메커니즘에 Header Manipulation 검사를 포함하도록 확대한다.

또한 응용프로그램에서 사용자에게 전달되는 모든 입력을 확인하는 것!!

%0d 또는 \r

%0a 또는 \n

와 같은 문자에 대해 반드시 점검을 하고 인코딩해서 특수한 기능을 제거하고 문자 그대로를 보여줘야 한다.

 

 

Weak Cryptographic Hash

Abstract

약한 암호화 해시는 데이터의 무결성을 보장할 수 없고 보안이 중요한 컨텍스트에 사용되어서는 안됨

 

Explanation

MD5 및 SHA-1은 메시지 및 기타 데이터의 무결성을 확인하는데 흔히 사용되는 암호화 해시 알고리즘이지만 약점이 발견 됨

 

Recommendation

SHA-224, SHA-256, SHA-512 를 사용한다.

 

 

Poor Style

Abstract

비 final public static 필드는 외부 클래스에 의해 변경될 수 있음

 

Explanation

public static int ERROR_CODE = 100; 와 같이 변수를 사용할 경우

오류코드를 변경하고 프로그램을 예기치 않은 방식으로 동작하게 만들 수 있음

 

Recommendation

필드를 상수값으로 노출시키려면 해당 필드는 public static final로 선언되어야 함. 또는 private 필드로 선언

 

 

Excessive Session Timeout

Abstract

지나치게 긴 세션시간 초과는 공격자에게 사용자 계정을 잠재적으로 손상시킬 수 있는 시간을 더 많이 제공함

 

Explanation

세션이 활성화 상태로 있는 동안, 공격자는 사용자의 암호를 무차별 대입하거나 사용자의 무선 암호화 키를 불법 복제하거나 열린 브라우저에서 세션을 제멋대로 쓸 수 있게 됨. 혹은 메모리가 해제되지 못하도록 하여 충분히 많은 세션이 만들어지는 경우 denial of service가 발생함

<session-config>

 <sessiont-timeout> -1 </session-timeout>

</session-config>

세션 시간 초과가 0 또는 0미만일 경우, 세션은 만료되지 않음. -1로 설정된 경우 세션은 무기한 활성화 상태 됨

 

Recommendation

30분 이하의 세션시간 초과를 설정.

 

SQL Injection

Abstract

사용자 입력을 받아 동적으로 SQl문을 생성하면 공격자가 SQL문의 의미를 수정하거나 임의의 SQL명령을 실행할 수 있음

 

Explanation

변수 이름 주변의 # 문자는 iBatis가 userName 변수를 사용하여 매개 변수가 있는 쿼리를 생성함을 나타냅니다. 그

러나, iBatis를 사용하면 $ 문자를 사용하여 변수를 SQL 문에 바로 연결할 수 있으므로 SQL injection에 대한 문이

열릴 수 있습니다.

 

Recommendation

iBastis에서 문자열 대체를 의미하는 $ 문자 대신 변수값 대입을 의미하는 #문자를 사용한다.

 

Privacy Violation

Abstract

고객 암호 또는 주민 등록 번호 등의 개인 정보 취급 부주의는 사용자 개인 정보를 침해할 수 있고 불법인 경우도 있음

 

Explanation

프로그램이 실행되는 운영환경을 신뢰하고 개인정보를 file system, 레지스트리, 또는 기타 로컬로 제어되는 리소스에 저장해도

무방하다고 생각하나, 해당 리소스에 대한 접근 권한을 가진 개인을 신뢰할 수 있다고 보장할 수 없음

다음과 같은 규제를 하나 이상 준수할 의무가 있음

세이프 하버 협정

GLBA(Gramm - Leach Bliley Act) 금융정보보호법

HIPAA(Health Insurance Portability and Accountability Act)의료정보보호법

California SB : 캘리=포니아 데이터베이스 보안침해 고지법

 

Recommendation

내부 개인 정보 지침을 작성하여 엄격하게 준수하고 응용프로그램이 개인 정보 데이터를 처리하는 방식을 구체적으로 기술한다.

개인정보와 관련된 데이터 형식을 입력하지 못하도록 입력데이터에 대해 필터링을 실시한다.

 

 

위험한 형식 파일 업로드(Unrestricted Upload of File with Dangerous Type)

 

서버측에서 실행될 수 있는 스크립트 파일(asp, jsp 등) 업로드 제한해야 함

=> 업로드하는 파일 타입과 크기 제한, 업로드 디렉토리를 웹서버의 다큐먼트 외부에 설정

=> 화이트리스트 방식으로 확장자만 업로드되도록 하고, 확장자도 대소문자 구분없이 처리

=>공격자의 웹을 통한 직접 접근을 차단. 또한 파일 실행여부를 설정할 수 있는 경우 실행 속성을 제거

 

 

신뢰되지 않는 URL 주소로 자동 접속 연결(URL Redirection to Untrusted Site, Open Redirect)

(Click)

response.sendResponse(shortcutInfo.url); 와 같이 사용자로부터 입력받은 url로 이동을 하는 경우

피싱(phishing) 공격에 노출되는 취약점을 가질 수 있다.

자동 연결할 외부 사이트의 URL과 도메인은 화이트리스트로 관리하고, 사용자 입력값을 자동 연결할 사이트 주소로 사용하는 경우에는 입력된 값이 화이트 리스트에 존재하는지 확인한다.