개요
- 로그인 방식을 지원하는 대표적인 두 가지 방식 Session과 JWT 개념에 대한 정리
JWT (Json Web Token)
Authentication vs Authorization |
---|
|
Authentication (인증): 로그인과 같이 사용자 혹은 프로세스의 신원을 확인하는 프로세스
Authorization (권한부여): 누가 무엇을 할 수 있는지 결정하는 규칙, JWT가 유용하게 사용되는 시나리오 중 하나
Session 방식
Session 방식 |
---|
|
- 클라이언트가 로그인을 위해 인증 정보를 서버에 전송
- 서버는 메모리에 사용자를 저장하고, 세션 아이디를 쿠키로 전달
- 클라이언트는 쿠키에 저장된 세션 아이디를 이용하여 요청
- 서버는 일치하는 세션 아이디를 메모리에서 검색한 후 응답
Q. 서버 인증 기반의 문제점?
- 세션을 DB에 저장해서 탐색하기 때문에 유저가 늘어날 수록 서버의 램이 과부하
- 여러 개의 프로세스를 돌리거나 서버 컴퓨터를 추가하는 것이 용이하지 않음
- 쿠키는 단일 도메인 및 서브 도메인에서만 작동하도록 설계되어 있어 여러 도메인에서 관리하기 번거로움
JWT (Json Web Token)
- JWT (Json Web Token) 은 JSON 개체로 안전하게 전송하기 위한 국제 표준 (RFC 7519)
- 디지털 서명이 되어 있으므로 확인하고 신뢰할 수 있음
JWT 방식 |
---|
|
- 클라이언트가 로그인을 위해 인증 정보를 서버에 전송
- 서버는 secret 정보를 이용하여 JWT를 생성하고, 클라이언트에게 전달
- 클라이언트는 로컬 혹은 브라우저에 저장해두었던 JWT를 이용하여 요청
- 서버는 JWT가 일치하는지 확인한 후, 응답
JWT 구조
- 크게 3개의 점으로 구분된 3가지 부분으로 구성된다.
xxxxx.yyyyy.zzzzz
- Header
- 헤더는 토큰 타입과 어떤 알고리즘이 쓰였는지를 나타낸다.
{
"alg": "HS256",
"typ": "JWT"
}
이 json은 Base64Url로 인코딩된 JWT의 첫번째 부분
-
Payload
- 토큰의 두번째 부분은 사용자 및 정보가 담겨있는 payload 부분
- payload에 담긴 정보는 인코딩만 되어 있기 때문에 누구라도 디코딩하여 확인할 수 있으므로 중요한 정보를 담으면 보안상 위험
-
Signature
- 마지막 Signature 영역을 생성하려면 인코딩된 header, 인코딩된 payload, secret, 헤더에 지정된 알고리즘을 이용하여 해싱한다.
- 만약 어느 하나라도 일치하지 않으면 완전히 다른 값을 갖게 된다.
토큰 작동 방식
- 로그인하면 JSON 웹 토큰이 반환
- 토큰은 자격 증명이므로 보안 문제를 방지하기 위해 세심한 주의 필요
- 일반적으로 토큰을 필요 이상으로 오래 보관해서는 안 되며, 또한 보안이 취약하기 때문에 민감한 세션 데이터를 브라우저 저장소에 저장해서는 안됨
- 앱에서는 설치된 앱 별로 안전한 저장 공간이 제공되지만 웹에서는 세션 인증이 나은 선택일 수도 있다.
Q. Token 인증방식의 장점?
- 무상태와 확장성, token은 클라이언트쪽에만 저장되므로 staeless 하며, 서버를 확장하기에 적합한 환경을 제공
- 쿠키를 사용함으로 인해 발생하는 보안 취약점이 사라짐
- 토큰을 사용하여 다른 서비스에도 권한 공유
Session vs JWT 차이점
- 서버에 인증 정보를 저장하지 않는다는 점이 상이
- 클라이언트의 요청마다 인증을 위해 DB를 탐색하는 과정이 필요하지 않고, 저장 공간도 필요하지 않음
CSRF의 이슈
- Cross site Request Forgery
POST /email/change HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
Cookie: session=yvthwsztyeQkAPzeQ5gHgTvlyxHfsAfE
email=wiener@normal-user.com
<html>
<body>
<form action="https://vulnerable-website.com/email/change" method="POST">
<input type="hidden" name="email" value="pwned@evil-user.net" />
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
CSRF의 보완책
-
CSRF 토큰 - CSRF 토큰은 서버 측 응용 프로그램에서 생성하고 클라이언트와 공유하는 고유한 비밀 및 예측 불가능한 값
- 양식 제출과 같은 중요한 작업을 수행할 때 클라이언트는 요청에 올바른 CSRF 토큰을 포함하여 전달
-
SameSite 쿠키 - SameSite는 웹 사이트의 쿠키가 다른 웹 사이트에서 발생하는 요청에 포함되는 시기를 결정하는 브라우저 보안 메커니즘
- 중요한 작업을 수행하기 위한 요청에는 일반적으로 인증된 세션 쿠키가 필요하므로, 적절한 SameSite 제한으로 인해 공격자가 사이트 간에 이러한 작업을 트리거 X
-
Referer 기반 검증 - 일부 응용 프로그램은 HTTP Referer 헤더를 사용하여 CSRF 공격을 방어
- 일반적으로 요청이 응용 프로그램의 자체 도메인에서 발생했는지 확인함