본문 바로가기

보안/프로그램

시큐어코딩 (JAVA)


1. 시큐어 코딩의 필수 쟁점


 - 아키텍처

 - 프로토콜

 - 클라이언트 & 서버 언어

 

최근 침해사고 피해 유형을 살펴보니


1. 모바일 보안 위협 증대

3. 개인정보 유출형 해킹사고

4. 홈페이지를 통한 악성코드 유포 지속


를 살펴보면 모두 웹환경이다.



기존 소프트웨어 개발자는 하드웨어가 버틸 수 있는지에 대해 고려하며 하드웨어 중심으로 개발했다. 이후 애플리케이션 개발자는 솔루션 중심과 정해진 프로토콜을 신경썼다. 그러다 웹 환경으로 넘어오면서 지금의 환경이 오픈된 환경이라 생각하고 개발해야하는데 실제 현실은 그렇지 않다. 물론 초기에는 정보를 모두 공개하는 환경이었긴 하지만 지금은 Private이 중요해짐에따라 정보 보호도 신경써서 개발해주어야한다.


기본적으로 열려있는 공간에서 막으려면 많은 것들을 생각해야한다. 웹은 직접들어오는 것도 있지만 우회하여 들어오는 경우도 있기 때문이다. 순수 개발자들을 보면 보안에 대한 이슈를 많이 알고있는 경험자들이 부족한 것이 가장 큰 문제이다. 



2. 소프트웨어 개발 방법론


현재 여러가지 방법론들이 나오지만 대표적으로 순수 소프트웨어만 개발하는 사람(코더)은 일을 할 수 있는 능력이 한계에 다달았다. 따라서 가이드를 내려주는 것이 가장 이상적이라 판단했고 시큐어를 고려한 소프트웨어 라이프 사이클을 지정했다.


 

 1) 구조적 방법론 (1970~)

   - 다양한 기법들을 하나로 통합 운영함

   - Operation 중심 (알고리즘, 프로세스)

  

 2) 정보 공합 방법론(1985~)

   -  데이터 중심

 

  3) 객체지향방법론(2000~)

   - (Operation, Data)

   - 비기능적인 요소가 영향을 끼칠 수 있음

   - 업무가 명확할 땐 좀더 data 중심으로,

   - 업무가 불명확할 땐 좀더 oepration 중심으로!

 

  4) CBD(Commonent based development) 방법론

   - 대형 Aoset 구조

 

  5) Asile 방법론

   - 현업에서 개발자와 소통하여 빠른 대응을 하는 방법론

   - 이때 소스코드는 직접 건드리지마라

   - 상속(1:1) 또는 관련성(1:N)을 이용

 

   6) UI/UX : 유연한 UI


SDLC 중 반복 위험 평가를 보면 기본적으로 소프트웨어는 기능적인 요구사항에 집중할 수 없기 때문에 반복적으로 확인을 해야한다. 그런데 이렇게 하다보면 소프트웨어가 엉망진창이 되어버린다. 소프트웨어는 보안도 중요하지만 이렇게 하면 객체지향의 유지보수의 효율성을 잃어버린다. 따라서 리팩토링을 신경써야하는데 이렇게 하기위해선 먼저 수정하기 전의 구조를 생각하고 먼저 소스코드를 변경한 뒤 수정한다. 


KISA에서는 매년 시큐어코딩에 관해 문서를 발행해왔다. 발표한 소프트웨어 개발 프로세스별 보안 활동을 살펴보면 보안 전문가가 중간에서 보안을 점검하라고 한다. 하지만 이건 실효성이 낮다. 그럴바엔 기획자와 개발자가 대화하는 동안 현재 개발하려고 하는 프로젝트의 보안이슈를 정리하는게 더 낫다 생각한다. 그리고 개발자는 신경안쓰는 동안 기획자와 보안 개발 담당자들이 최대한 보안 이슈가 될 만한 것에 대한 목록들을 만들어서 업무를 줄때 같이 넘기는 것이 바람직하다. 지금부터 아래에 있는 시큐어코딩 주제는 개발자가 자주 실수하는 것들을 정리한 것이다. 에러는 최대한 줄여주는 것이 좋다. 에러 발생시 그 에러에 관한 정보가 웹페이지에 노출되게 되고 시스템 환경이 공개될 우려가 있기 때문이다.



3. 예외처리 작성


함부로 에러가 발생할 수 있는 위치에 System.err.printf()를 쓰지 말자. 에러가 발생하면 시스템 환경이 외부에 공개될 위험이 있기 때문이다. 만약 너무 많아 수정하기 힘들다면 함수위에 System.setOut(new PrintStream("user_log.txt")를 쓰면 여기에 로그가 찍히게 된다.





4. 널포인터 역참조 

구현을 하면서 지속적으로 널 포인터 역참조를 고려하자. 아래 코드를 보면 생성자에서 Collection을 초기화하지 않고 외부 객체의 Collection을 사용하면 널포인터 역참조의 문제에 빠질 수 있다. 




5. 안전한 데이터 관리 - Synchronized를 사용해라


우선 쓰레드에서 대해 알아보자. 자바는 기본적으로 모든 것이 쓰레드로 되어있고 풀을 활용해 쓰레드를 관리한다.  그룹쓰레는드는 그냥 메인함수로 봐도 좋다. 잘 모르겠으면 Thread.currentThread()를 호출해라.





웹 개발 시 Thread를 상속받으면 더 이상 상속받을 수 없으므로  Runnable 인터페이스를 상속받는 run을 재정의하는 것을 더 추천한다. 상속1은 멀티쓰레드를 실행하기 위해서 쓰이고 thread.start(); 는 VM에게 쓰레드의 시작을 알리는 함수이다.




Synchronized는 쓰레드의 동시성을 해결할 수 있는 키워드다. 여러 쓰레드가 동시에 자원을 접근할 때 자원문제가 문제에 빠질 수 있는 이러한 문제를 해결해준다.  



쓰레드의 생명 주기는 다음과 같다. 실행중에 잠이 들때 Synchronized는 block이 아닌 lock pool에 보내진다.




웹은 기본적으로 Map과 Collection으로 데이터를 메모리에 저장하고 주고 받는다. 이제 클라이언트와 서버가 데이터를 주고 받을 때 여러 쓰레드가 공유데이터를 사용하면 synchronized를 고려해라.


Collection 을 상속받는 자료구조 중에 Vector은 좀 속도가 느리다. 그 이유는 Synchronized 로 구현되어 있기 때문이다. ArrayList와 같은 구조이므로 이를 사용하면 된다.


만약 List ,Set Map을 사용하고 싶으면 


Collections.synchronizedList(new ArrayList<T>())


Collections.synchronizedSet(new HashSet<T>())


Collections.synchronizedMap(new HashMap<T>())


위의 Collections 를 사용하면 된다. (좋은 방법은 코드를 잘개 쪼개고 직접 synchronized를 붙여주는게 좋다)