[Java]시큐어 코딩

728x90
반응형

 

*이 글은 행정안전부 시큐어코딩가이드(Java)를 개인적으로 기억하기 위해 정리한 글입니다.

 

 

입력 데이터 검증

1.  파일 업로드 확장자 유효성 체크

- 서버에서 실행될 수 있는 스크립트 파일(asp, jsp, php 파일 등)을 업로드 가능하게 하면 공격자가 이 파일을 통해 시스템 내부 명령어를 실행하거나 외부와 연결하여 시스템을 제어할 수 있다. 

- 업로드하는 파일 타입과 크기를 제한해야 한다. 

 

2. SQL Injection + XQuery, XPath, LDAP 삽입

- 입력 데이터에 대하여 특수문자 및 쿼리 예약어를 필터링해야 한다. 

- mybatis를 사용할 경우 변수에 #을 사용한다.

 

3. 디렉토리 경로 조작

- 파일 이름을 입력받는 경우 위험 문자열(",/,\)을 제거해야한다.

 

4. 정수 오버플로우

- 존재하지 않는 메모리 주소를 참조하여 발생하는 오버플로우를 방지해야한다.

 

캡슐화

- 중요한 데이터를 충분히 캡슐화 하지 못할 경우에 데이터 누출이 불가피해지기 때문에 보안 측면에서 굉장히 중요하다. 

 

1.  변수 범위(Scope) 주의

/************
* 잘못된 코딩
************/
public class printName extends HttpServlet {

	private String name;	
	
    public void getName(HttpServletRequest request){
    	name = request.getParameter("name");
    }
}

====================================================================================

/************
* 올바른 코딩
************/
public class printName extends HttpServlet {
	
    public void getName(HttpServletRequest request){
    	String name = request.getParameter("name");
    }
}

 

2. 외부에 정보를 유출할 가능성이 있는 불필요한 디버그 코드

 

3. 시스템 데이터 정보 노출

- 구체적인 오류 내용과 defaultPath에 대한 정보가 유출되지 않게 해야한다.

- 시스템 관련 정보는 에러메세지에 포함시키지 않는 것이 보안상 안전하다.

/************
* 잘못된 코딩
************/
public class printName extends HttpServlet {
	
    public void getName(HttpServletRequest request){
    	try{
        	....
        }catch(Exception e){
        	System.out.println(e.getMessage());
        }
    }
}

====================================================================================

/************
* 올바른 코딩
************/
public class printName extends HttpServlet {
	
    public void getName(HttpServletRequest request){
    	try{
        	....
        }catch(IOException e){
        	//end user가 볼 수 있는 오류 메세지 정보를 생성하지 않아야 한다.
        	System.out.println("IOException Occured");
        }
    }
}

 

4. private으로 선언한 배열을 public으로 선언된 메소드에서 리턴되면, 해당 배열의 주소값이 외부에 공개되서 외부에서 배열 수정이 가능해진다. 

- private으로 선언한 배열 그대로를 리턴하지말고 필요한 경우 복제본을 만들어 리턴해야한다. 

/************
* 잘못된 코딩
************/
public class printName extends HttpServlet {

	private String[] names;
	
    public String[] getNames(HttpServletRequest request){
    	return names;
    }
}

====================================================================================

/************
* 올바른 코딩
************/
public class printName extends HttpServlet {
	private String[] names;
    
    public String[] getName(HttpServletRequest request){
    	String[] returnNames = null;
        if(this.names != null){
        	returnNames = new String[names.length];
            for(int i=0; i<names.length; i++){
            	returnNames[i] = names[i];
            }
        }
    	return returnNames;
    }
}

 

5. private 배열에 public 데이터 할당

- private 배열을 외부에서 접근할 수 있게 된다.

/************
* 잘못된 코딩
************/
public class printName extends HttpServlet {

	private String[] names;
	
    public void getNames(String[] user){
    	this.names = user;
    }
}

====================================================================================

/************
* 올바른 코딩
************/
public class printName extends HttpServlet {
	private String[] names;
    
    public void doPost(String[] user){
    	this.names = new String[user.length];
        for(int i=0; i<names.length; i++){
        	this.names[i] = user[i];
        }
    }
}

 

6. 변경되면 안되는 public 멤버 변수는 반드시 final로 한다. 

- 외부에서 수정되면 안되는 변수는 final 키워드로 선언해야한다.

public static final String APIKey = "abcdefg";

 

API 오용

1. DNS lookup에 의존한 보안결정

- 도메인명에 의존해서 보안결정(인증 및 접근 통제 등)을 하면 안된다.

- DNS lookup에 의한 호스트 이름 비교를 하지 않고 직접적인 IP 주소를 비교해야 한다. 

 

2. Null 체크

 


참고자료

https://www.mois.go.kr/frt/bbs/type001/commonSelectBoardArticle.do%3Bjsessionid=fr7QaTyG2gK5o02XJnYETp3havIQ1MGLKMYdWaaEe5me9IOk932SIy2BbP1AM08Z.mopwas54_servlet_engine1?bbsId=BBSMSTR_000000000012&nttId=42152 

 

시큐어코딩가이드(C, Java) | 행정안전부> 정책자료> 간행물> 간행물

행정안전부 홈페이지에 오신것을 환영합니다.

www.mois.go.kr

 

728x90
반응형