Maenya's Techlog

[20210504] Java 시큐어 코딩의 필요성 본문

프로그래밍/Java | Spring

[20210504] Java 시큐어 코딩의 필요성

ming235 2021. 5. 4. 17:38

 

국내 기업에서도 여러 가지 이슈들로 보안취약점이 드러나는 경우가 있다.

 

 

1. SQL 인젝션 사례

여기어때 해킹사건, 왜 '과징금 3억원' 경징계 나왔나 매출액 3%까지 부과 가능…법상으론 높은 징계

97만여명의 숙박업소 이용 이력 정보가 유출되면서 피해자들이 협박 문자까지 받았던 여기어때 해킹 사건에 대해 방송통신위원회가 서비스 운영사인 위드이노베이션에 과징금 3억100만원, 책임자 징계 권고 등 행정처분을 내렸다.
...
위드이노베이션은 ▲개인정보처리시스템 다운로드 등의 접근권한이 있는 개인정보취급자의 컴퓨터를 외부 인터넷망과 업무망으로 분리하지 않은 점 ▲적절한 규모의 침입차단탐지시스템을 설치하고 개인정보처리시스템에 접속한 IP 등을 재분석해 불법적인 개인정보 유출 시도를 탐지하지 않은 점 ▲해킹을 당한 마케팅센터 웹페이지에 대해서 웹페이지 취약점 점검을 수행하지 않은 점 ▲고객상담사 등에게 파일 다운로드 권한이 있는 관리자페이지 접근권한을 부여하는 등 접근권한을 과하게 부여한 점 ▲인사이동 시 취급자의 접근권한을 지체 없이 변경하지 않아 해커가 이를 악용해 개인정보 파일을 다운로드 한 점 등 정보통신망법 제28조제1항에 따른 접근통제 조치 전반을 소홀히 한 점이 확인됐다.

 

 

2. URL parameter 조작 사례

주문 번호 쳤는데 신상 '탈탈'…책 사려다가 봉변
국내 최대 인터넷서점인 YES 24에 고객정보가 무방비로 노출됐습니다. 주문 번호만 치면 다른 사람에 개인정보까지 다 볼 수 있었습니다. ...
장 씨가 했던 것처럼 취재진도 YES 24 사이트에서 임의로 주문 번호를 쳐봤습니다. 해당 번호를 받은 다른 주문자의 개인 정보를 확인할 수 있었습니다. 이렇게 스무 명의 개인정보를 입수해 직접 확인해 봤는데, 모두 YES 24 고객들이었습니다....
YES 24 측은 보안 점검 과정의 실수로 지난달 초부터 3주 동안 개인정보가 노출된 사실이 있다고 인정했습니다.

 

 

좀 오래된 사례이지만 보안취약점을 빠르게 이해시켜주는 사례로 보여서 가져오게 되었다.

 

아래는 그에 따른 JAVA 시큐어 코딩의 예시이다.

 

 

[SQL injection 취약점 발생]

 

/* SQL injection에 취약한 코드*/
String userId=request.getParameter("userId");
String password=request.getParameter("password");
...
Statement stmt = conn.createStatement();
ResultSet result =
   stmt.executeQuery("select count(*) as count from student where userid='"+userId+"' and password='"+password+"'");

외부입력값을 동적으로 SQL 실행문을 만들어서 사용할 때에 주로 나타난다.

 

악의적으로 drop table, drop database도 가능하다.

 

 

 

[해결방안]

 

 

- 유저에게 받은 값을 그대로 넘기지 않기

- client 측에서 값을 받을때 검증해서 받기

- client에서 넘어온 값을 서버에서도 검증해서 받기 

 

- spring boot JPA 사용!!

 

stackOverFlow에 따르면 입력받은 값이 그 자체로 JPA에서는 value로 사용되기 때문에 injection이 불가하다고 한다.

@Query(query="select count(*) as count from student where userid=:userId", nativeQuery = true) 
int findUser( @Param("userId") String userId);

내부적으로 PreparedStatement 처럼 동작하여 injection으로 동작하는 것이 아니라,

value로 값이 들어가게 되어 안전한 상태로 유지된다.

[main] hello.Application                        : InjectionTest:
[main] org.hibernate.SQL                        : select count(*) as count from student where userid = ?
Hibernate: select count(*) as count from student where userid  = ?
[main] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [VARCHAR] - [admin' OR '1'='1]

PreparedStatement를 사용하는 경우 파라미터로 들어가는 값을 바인딩하여 사용한다. 바인딩데이터는 SQL문법이 아닌 컴파일언어로 처리하기 때문에 문법적 의미를 가질 수 없으므로, 바인딩 변수에 SQL injection query를 넣더라도 의미있는 쿼리로 동작하지 않는다.

 

 

 

 

 

출처 데브원영