본문 바로가기
자바 시큐어 코딩

클라이언트에 암호화되지 않은 민감-데이터 제한

by 웹하는빡통 2020. 4. 2.

클라이언트-서버 모델을 사용하는 응용프로그램을 작성할 때 사용자 인증 정보와 같은 민감-정보를 클라이언트 측에 저장하면 클라이언트가 공격에 취약할 경우 허가되지 않은 벙법으로 민감-정보가 노출된다. 

 

웹 응용프로그램에서 이 문제에 대한 가장 보편적인 완화책은 쿠키를 클라이언트에게 제공하고 민감-데이터는 서버에 저장하는 것이다. 쿠키는 웹 서버에 의해 생성되고 일정 기간 동안 클라이언트에 저장된다. 클라이언트가 서버에 다시 연결할 때 클라이언트가 서버에게 자신을 식별하도록 하는 쿠키를 제공하면 서버가 민감-정보를 제공하는 것이다.

 

쿠키는 XSS공격으로부터 민감-정보를 보호하지 못하는데 XSS공격이나 클라이언트를 직접 공격해서 쿠키를 얻을 수 있는 공격자는 쿠키를 이용하여 서버로부터 민감-정보를 탈취한다. 만약 서버가 제한 시간(15분)경과 후에는 세션을 무력화하도록 한다면 이러한 위험은 시간에 한정적으로 된다.

 

보통 쿠키는 짧은 문자열인데 만약 쿠키가 민감-정보를 포함하고 있다면 암호하되어야 한다. 민감-정보란 사용자 이름,패스워드, 신용카드 번호등 사용자 개인을 식별할 수 있는 기타 정보등으로 정의한다. 

 

부적절한 코드.

이 예제에서 로그인 서브릿(sublet)은 이후의 요청에서 사용자를 식별하기 위해 사용자 이름과 패스워드를 쿠키에 저장한다. 여기서 리멤버-미(remember-me)기능을 구현하는 것은 안전하지 않는 방법이다. 이유는 클라이언트 머신에  엑세스할 수 있는 공격자는 클라이언트로부터 정보를 직접 얻을 수 있기 때문이다. 

 

remember-Me: 웹 응용프로그램에서 사용자가 로그인 후 세션이 종료된 후에도 로그아웃할 때까지는 해당 머신의 데이터에 엑세스할 수 있도록 하는 기능을 말함. 이것을 구현하는 한 가지 방법이 쿠키를 이용하는 것이다.

 

Java Servlet: 자바를 사용하여 웹페이지를 동적으로 생성하는 서버측 프로그램 혹은 그 사양을 말함. 흔히 "서블릿"이라 불린다. 자바 서블릿은 웹 서버의 성능을 향상하기 위해 사용되는 자바 클래스의 일종

 

toCharArray(): 문자열을 char형 배열로 변환
getValue():쿠키 값 얻기
ex) String 변수 ="cookie".getValue()

valueOf(): 입력받은 인자 값을 지정된 number 객체 형으로 변환하여 반환하는 함수이다. 이 인자값은 primitive data type(원시 데이터형 - byte, int, long, double boolean등 자바 키워드로 이미 지정된 데이터 형) 또는 문자열 등이 될 수 있다. 

Arrays.fill(): 배열의 사이즈만큼 지정한 특정 값으로 한번에 초기화를 시킬 수 있다.

 

적절한 코드.

이 예제는 사용자 이름과 안전한 랜덤 문자열을 쿠키에 저장함으로써 리멤버-미 기능을 구현한다. 또한 HttpSession을 사용하여 세션 상태를 유지한다. 

 

서버는 사용자 이름과 안전한 랜덤 문자열과의 짝을 유지한다. 사용자가 "remember-me"를 선택하면 doPost()메소드제공된 쿠키가 유효한 사용자 이름과 짝이 되는 랜덤 문자열을 포함하고 있는지 검사한다. 

 

만약 짝이 맞으면 서버는 사용자를 인증하고 "ex)) java page"페이지로 연결시킨다. 그리고 일치하지 않으면 서버는 클라이언트에게 오류를 반환한다. 또한 사용자가 "remember me"를 선택했지만 클라이언트가 유효한 쿠키를 제공하지 못하면 서버는 사용자에게 다른 인증정보를 가지고 인증하도록 요구한다. 그리고 인증이 성공하면 서버는 리멤버-미 특성을 가지고 새로운 쿠키를 생성한다.   

 

이 시큐어코딩은 현재 세션을 무효화하고 새로운 세션을 생성함으로써 session-fixation attack을 피한다. 또한 클라이언트 엑세스 시간 간격을 15분으로 제한함으로써 공격자가 session-하이재킹 공격을 할 수 있는 시간적 기회를 단축시키나다. 

 

세션-하이재킹: 유효한 사용자 세션을 탈취하여 인증을 우회하는 공격 기법.

 

session.setMaxInactiveInterval(60 * 15): 세션 유효시간을 설정함. 

1. getSession(), getSession(true)
 - HttpSession이 존재하면 현재 HttpSession을 반환하고 존재하지 않으면 새로 세션을 생성한다.

2. getSession(false)
 - HttpSession이 존재하면 현재 HttpSession을 반환하고 존재하지 않으면 새로 생성하지 않고 그냥 null을 반환한다.

[참고] session.isNew : 새로 생성된 세션이면 true를 리턴.
[참고] getSession(), getSession(true)는 null 체크없이 바로 getAttribute()를 사용해도 무방하지만, getSession(false)는 null을 리턴할수 있기 때문에 null체크를 해야 합니다.

 

코드비교.

왼쪽은 부적절한 코드, 오른쪽은 적절한 코드이다. 

댓글