[웹 보안 Web Security] 세션 (Session) ID 의 발급과 활용 그리고 쿠키 탈취를 이용한 계정 도용 방어 개발 이것저것

일단 이 내용을 이해하기 위해서는, 쿠키와 세션에 대해서 알아야 하는데..

이것을 모르시는 분들은 여기 를 방문하셔서 HTTP 와 세션, 쿠키 에 대해 그 정의를 한번 읽어봐 주시기 바랍니다 ㅎㅎ

영어 잘하시는 분들은 아래 링크를 참고하시면 더 직방입니다 ㅎㅎㅎㅎ

그럼 이제부터 시작,

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

웹상의 신원 정보 도용

일단 HTTP 프로토콜이라는게 ConnectLess, StateLess 하기 떄문에, 매번 들어오는 HTTP Request 에 대해 "넌 누구냐?" 라고 물어봐야한다.
그래서 대부분의 웹서버는 세션정보를 사용자의 쿠키에 박아 "넌 홍길동 이구나!!" 를 식별한다.
로그인이라는게 그래서 존재하는 것이 아니겟는가 ㅎㅎㅎ.

자, 그렇다면 !! 내 세션 정보를 다른사람에게 빼앗겼다면 어찌 되는거지?
온라인상에서는 얼굴을 확인할 수 있는것도아니고, 민증을 까라고 할수도 없는 노릇이다.
그냥 세션정보를 빼앗기면 내 신원정보 자체를 도용당할 수 있는 그런 상황이 되버리는 것이다.

그래서 이러한 위험한 상황을 막기위해 웹 서버개발자는 어떻게 대비를 해야할까?
기본적인 잘 알려진 웹 프레임워크에서는 이러한 문제점에 대한 처리를 어느정도 자체적으로 해결해주고 있다.
하지만.. 알고는 있어야 하지 않을까?

자, 그럼 무엇이 위험한 것이고, 이걸 어떻게 해결해야 할지 알아보자.

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

온라인상의 똑똑한 사용자 식별 노하우

웹으로 들어오는 HTTP Request 만 가지고 우리는 누가 누구인지 구분해야한다.
크게, 웹 서비스는 사용자를 3가지 분류로 구분한다.

1. 처음 방문한 사용자.
2. 방문한적은 있는데 로그인 하지 않은 사용자
3. 로그인을 이미 한 사용자.

(더 엄격히 구분을 할경우, 3번은 로그인을 한지 얼마 안된 사용자와, 오래된 사용자로 또 나눌 수 있음)

1번 사용자의 경우 웹서버는 세션ID를 발급하고,
2번 과 3번의 경우는 사용자의 세션 ID를 가지고 적절한 액션을 취한다.

그럼 여기서 가장 중요한 것은 바로 세션 ID 인데....

이것을 어떻게 만드느냐와 어떻게 활용하느냐가 가장 중요한 포인트가 되겠다.

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

1. 세션 ID 의 생성

정확하게 세션 ID 를 만드는 로직은 뭐 어짜피 개발자 마음이므로 정의할수가 없는 부분이다.
대신, 어떤 데이터를 활용해야하는지를 적어본다면 아래와 같다.

- User ID : 서비스에서의 사용자 고유 식별자

- Secret Key : 서버 자체에서만 사용하는 비밀 키, 서버가 통쨰로 털리기 전까지 이 정보는 절대로 외부로 노출될 일이 없다. ㅎ

- HTTP 헤더의 User Agent : HTTP Request 를 생성하는 소프트웨어(주로 웹 브라우저)는 그것의 종류와 버전 그리고 Device의 OS 와 같은 정보를 Header에 담아서 보낸다. 그리고 이것은 만일 실 사용자와 공격자의 Device 및 Browser 가 완벽히 일치하지 않을경우, 그 값이 다르다.

- HTTP 헤더의 Host : HTTP Request 가 생성된 서버의 Host (= 도메인 네임)와 포트번호를 알 수 있다.

- HTTP 헤더의 X-Forwarded-For : HTTP Request 가 생성된 서버의 (또는 네트워크 게이트웨이의) 공인 IP 주소를 알 수 있다. 하지만 이 헤더 Key는 비공식이기 때문에 있을수도, 없을 수도 있다.

위 정보들을 적당히 조합하여 세션 ID를 발급하게 될 경우,
쿠키 탈취로 인해 세션ID가 해커에게 노출 되었다고 하더라도 그것이 곧바로 도용될 수는 없는 이점을 가질 수 있다.

훨씬 더 강한 보안을 걸고 싶다면, 웹서비스를 HTTPS SSL이 가능하도록 세팅한 다음, 최초 쿠키를 발급할 때, HTTPS 통신일 경우에만 세션 정보를 전달 받을 수 있도록 하는 방법이 있다.


2. 세션 ID 의 발급부터 폐기까지

자, 그럼 위와 같이 만든 세션ID를 어떻게 써먹길래, 이것으로 사용자를 안전하게 식별한다는 것일까?

우리가 알만한 모든 웹서비스들은 모두 세션 ID를 발급한다. 그리고 그것들은 대체로 알파벳, 특수문자, 숫자 등이 난잡하게 섞인 알아볼수 없는 문자인 경우가 많다.

웹 서비스들은 이 세션 ID를 발급함과 동시에 해당 ID를 가진 사용자의 행동정보를 DB에 쌓아둔다.

일반 가게에 빗대어 이야기 하자면, 고객명단과 비슷한 것이며, 우리는 이 고객들을 얼굴, 성명, 주민등록번호 등을 바탕으로 인식하지만 웹서비스는 그 대신 세션 ID를 이용하여 누가 누구인지를 구별한다는 것이다.

자, 그럼 세션 ID의 발급과 활용, 그리고 폐기에 대해 알아보자.

1. 사용자가 웹서비스에 URL을 주소창에 치고들어와 웹서버에 HTTP Request 날림.

2. HTTP Request를 받은 웹서버는 나름의 세션ID 생성 로직으로 HTTP 프로토콜에서 제공되는 정보만을 바탕으로 세션ID를 생성하고 그것이 자신의 세션 DB에 존재하는지(기존 사용자) 존재하지 않는지(신규 사용자) 구분하여 아래 2가지 액션을 취함.

   - 기존 사용자 : 세션ID를 가지고 기존의 사용자의 서비스 이용정보를 들고와서 요청받은 내역의 결과 화면을 되돌려 줌

   - 신규 사용자 : 사용자의 브라우저 에게 발급한 세션ID 를 쿠키에 저장하도록 함. 보통 이 경우, 로그인이 필요한 페이지에 접근 했다면 로그인 페이지로 리다이렉션.

3. 사용자는 발급받은 세션ID 를 그 서비스를 사용하기 위한 매 요청 시마다 웹서버에게 전달하고, 서버는 이를 바탕으로 2번의 과정을 반복적으로 수행하게 됨.

4. 그리고 사용자가 용무가 끝났다면 더이상 웹서버로 요청을 날리지 않을것이고, 그 순간 이후로 특정 세션ID의 마지막 사용 시각은 멈춰있을거임.

5. 서버 입장에서는 한번 발급하였던 세션ID의 마지막 사용시각을 기준으로 너무 오래된 세션 정보는 삭제하거나 같은 세션ID로 접근하는 사용자가 있다고 하더라도 폐기된 세션정보로 인식하여 새로운 세션 ID를 발급한다.

※ 서비스 기간이 길면 길수록 서버에 쌓이는 세션ID는 계속 늘어날 것이다. 만일 이 데이터가 충분히 많이 쌓이게 될 경우, 접속시각에 상관없이 세션ID를 그대로 활용하여 기존 사용자의 정보를 되돌려 주게 된다면, 자칫 잘못할 경우 매우 위험한 보안 사고가 발생할 수도 있다. 사용자 A가 사용했던 세션ID 가 매우 오랜시간 뒤에 B가 접속했을때 동일한 세션ID를 생성해 낼수도 있기 때문이다.

(이것은 Hash 함수가 항상 서로다른 Input 에 대해 Unique 한 Value 리턴을 해주지 못한다는 취약점과 같은 맥락이다.)


어쨋든,, 이와같이 세션ID에 대한 이야기를 한번 해보았다.
누군가에게는 도움이 되었기를 ...

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


덧글

  • 2017/01/20 16:18 # 삭제 비공개

    비공개 덧글입니다.
  • 졸린미어캣 2017/01/20 19:55 #

    방문 감사합니다 ^^
※ 로그인 사용자만 덧글을 남길 수 있습니다.


통계 위젯 (블랙)

59174
845
185326

GoogleAdsenseResponsive

Cluster map