카테고리 없음

쿠키 / 세션 / JWT / 보안 이슈

Campkim 2022. 1. 7. 22:54

인증과 보안에 많이 사용되는 상기 개념들을 정리하는 목적의 포스팅입니다.

포스팅내용

1. 쿠키 / 세션

2. JWT

3. 보안이슈

 

HTTP 쿠키

HTTP는 요청은 Stateless하다는 특징을 가지고 있다. 쉽게 말해 상태관리가 안된다는 말이다.

각각의 요청은 독립적이고 서버 입장에서는 클라이언트를 식별한다거나, 이전 요청에 대해 연관지어 응답하지 않는다.

이러한 특징을 보완해주는 것이 쿠키이다. 클라이언트 요청헤더에 쿠키가 담겨서 서버로 전송되고, 서버는 쿠키의 정보를 참고한다.

클라이언트 측 쿠키 저장 위치

주로 3가지 용도로 사용된다.

세션 관리(Session management) - 서버에 저장해야 할 로그인, 장바구니, 게임 스코어 등의 정보 관리

개인화(Personalization) - 사용자 선호, 테마 등의 세팅

트래킹(Tracking) - 사용자 행동을 기록하고 분석하는 용도

클라이언트 - 서버 요청시 요청헤더에 포함된 쿠키

 

최초의 쿠키는 서버쪽 response 헤더에 포함된 set-cookie 요청에 의해 셋업된다. key : value 형식으로 보인다.       

서버측 응답 헤더   

쿠키 셋업과 함께 Expires(날짜) 혹은 Max-age(기간)를 설정하여 쿠키의 라이프타임을 설정 가능하다.

HttpOnly 설정 방법

** HttpOnly라는 옵션이 있다. 아래에서 설명할 XSS공격으로 부터 세션의 쿠키 탈취를 막기 위한 방법이다. HttpOnly를 설정하면, 해당 쿠키는 Javascript의  document.cookie API에 접근 불가능하다. 

 

 

Session

서버에서 유저 정보 / 로그인 여부 식별을 위해 사용된다. 

일반적인 메커니즘은 최초 유저 인증 성공 이후 서버에서 세션을 저장한다. 세션 저장후 response를 통해 유저의 쿠키에 세션 id가 저장되도록 한다. 유저측에서 HTTP 요청할때마다 session id가 포함된 쿠키가 헤더에 포함되며, 서버는 해당 session id와 session storage에서의 정보를 대조후 유저, 로그인정보를 식별한다.

 

그렇다면, 세션은 어떤 형태로 저장되어 있을까 ? 

크게 3가지 형태로 저장 가능하다.

1. In memory

- 앱 구동중인 서버의 memory. 

좋은 방법이 아니다. 서버가 죽는 경우, 로그인 유저가 늘어나는 경우를 생각해보면 된다.

메모리는 비싼 자원이다. 

 

2. File storage

- 서버의 특정 디렉토리

서버가 죽어도 괜찮다. 하지만 문제가 있다. 로드밸런싱을 해야하는 상황을 판단해보면 좋다.

 

3. Database storage 

- file storage 대신에 DB에 저장

1,2 의 경우 보완이 될 것 같다. 다만 매번 대조할때마다 DB로의 I/O 작업이 필요할 것으로 생각된다.

 

인증과 관련된 만큼 보안 관련 사항들을 인지하고 있으면 좋을 것 같다. 

XSS (Cross-site Scripting) -  사용자의 브라우저에서 특정 스크립트를 실행시켜서 탈취하는 방식 / Http only 혹은 이스케이프라는 방식으로 태그를 막는 방법이 있다고 한다. 

 

CSRF (Cross-Site Request Forgery) - 서버로 부터 인증되어 있는 사용자로부터 서버에 접근하게 하여 의도치 않은 행동을 하게 하는 방식 

 

* 종종 다양한 웹서비스를 사용해보며 비밀번호 혹은 회원정보를 변경할 일 이 있을 때, 다시 로그인을 해야하는 경우들이 있었다.  사용자 입장에서는 귀찮고 이해가 안됬었는데 CSRF 공격에 대해 알고나니 그러한 이유를 알게 되었다.

 

 

JWT (Json Web Token)

 

Token은 인증에 사용되는 String 형태의 데이터라고 이해했다.

Token은 Header : Payload : Signature 로 나뉘어져 있다. Header에 서명알고리즘, 토큰타입이 들어있다.

서버는 토큰을 받았을 때, Header의 method를 참고하여 토큰을 다시 암호화해보고 Signature랑 대조하는 방식으로 토큰의 유효성을 판단한다. 만일 payload가 변경이 되었다면 Signature가 변경되게 된다.

*초기 토큰 암호화 시점에 서버는 서버만 가지고있는 개인키를 사용하기 때문에, 유저는 함부로 위조하지 못한다.

 

즉 클라이언트 쪽에서는 데이터 열람만 가능하고 실질적으로 수정은 서버에서만 가능하다.  

 

JWT의 장점으로는 유저의 인증정보 저장에 서버 리소스가 필요하지 않다는 점이다. 

인증에 필요한 데이터를 유저가 들고 있고 서버는 유효한 데이터인지 식별만 한다.

 

서버의 메모리, 파일 혹은 DB 리소스는 필요하지 않지만 보안적으로는 마찬가지로 단점이 있다.

JWT는 어디에 저장되어 보내져야할까?

Localstorage, session storage의 경우 Session과 마찬가지로 XSS 공격으로 접근이 가능해진다. 오히려 쿠키보다 위험하다.

하지만 쿠키에 저장된다면, 마찬가지로 CSRF 공격에 취약해진다. 세션보다 더 보안이 좋다거나 그렇지는 않은  것 같다.

 

쿠키, 세션보다 데이터 크기가 크다는 단점도 가지고 있다.

서버 리소스를 활용하고 있지 않기 때문에 토큰이 탈취당하면 만료시까지 대처가 어렵다는 단점도 있다. Session의 경우 서버에서 리소스를 관리하기 때문에 Session자체를 지워버리는 방법이 있다. 

이러한 이유로 JWT 사용시에는 유효기간을 짧게 가져가는 방법이 많이 채택되는 것 같다.

 

 

 

 

https://developer.mozilla.org/ko/docs/Web/HTTP/Cookies

 

HTTP 쿠키 - HTTP | MDN

HTTP 쿠키(웹 쿠키, 브라우저 쿠키)는 서버가 사용자의 웹 브라우저에 전송하는 작은 데이터 조각입니다. 브라우저는 그 데이터 조각들을 저장해 놓았다가, 동일한 서버에 재 요청 시 저장된 데

developer.mozilla.org