JWT (JSON Web Token)
개념
JWT (JSON Web Token)
사용자 인증 및 정보 전달을 위해 JSON 형식으로 데이터를 안전하게 인코딩하여 생성된 토큰입니다.
JWT 구조
JWT는 Header
, Payload
, Signature
3부분으로 나뉘어 있으며 .
으로 구분됩니다.
형식 : xxxxx.yyyyy.zzzzz
Header는 토큰의 타입과 사용된 서명 알고리즘을 나타냅니다.
{ "alg": "HS256", "typ": "JWT" }
Payload는 사용자의 정보나 속성을 나타내는 Claim이 담겨있습니다. 즉, 보내고자 하는 데이터 자체를 의미합니다.
{ "sub": "1234567890", "name": "John Doe", "admin": true }
Signature는 인코딩된 헤더와 페이로드를 비밀키 및 헤더에 지정된 알고리즘을 사용해 생성된 값으로, JWT의 무결성과 신뢰성을 검증하는 역할을 합니다.
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
등장 배경
기존에 사용하던 인증 방식인 Cookie와 Session의 단점을 보안하기 위해 JWT가 등장했습니다.
보안 이슈
XSS (Cross Site Scripting)
- 사용자를 대상으로 한 공격으로, 게시판이나 웹메일 등에 악성 스크립트 코드를 삽입하여 개발자가 의도하지 않은 기능을 실행하게 만드는 보안 취약점 공격입니다.
- 주로 쿠키, 토큰, 기타 중요한 정보를 훔치는 용도로 사용됩니다.
- 스크립트로 접근할 수 있는 곳에 토큰이 저장되어 있으면 XSS 공격에 취약해집니다.
localStorage
httpOnly
로 설정되지 않은 Cookie
CSRF (Cross Site Request Forgery)
- 사용자가 자신의 의도와는 무관하게 공격자가 의도한 행위를 서버에 요청하게 하는 공격입니다.
- 사용자가 이미 로그인되어 있고, 브라우저가 요청 시 자동으로 쿠키를 전송하는 점을 악용합니다.
JWT 저장위치
프론트에서 보통SessionStorage
,LocalStorage
,Cookie
에 보관됩니다.
SessionStorage
새로고침 및 탭이 닫히면 데이터가 사라지기 때문에 사용자 경험 측면에서 탈락LocalStorage
스크립트로 접근 가능, XSS 취약
LocalStorage에 저장된 JWT는 브라우저가 자동으로 서버에 보내지 않으므로 CSRF는 안전Cookie
XSS, CSRF 모두 취약
HttpOnly
속성을 통해 script에서 접근 불가능하도록 처리 -> XSS 공격 방어
SameSite
속성을Strict
또는Lax
로 설정 -> CSRF 공격 방어
- SameSite
쿠키가 외부 사이트 요청에 자동으로 포함되지 않도록 설정
SameSite = Strict
: 같은 사이트에서만 전송SameSite = Lax
: 외부사이트의 GET 요청에 대해서만 쿠키 전송SameSite = None
: 외부 사이트에서 요청 가능 (Secure 쿠키에 한해서)
결론: Cookie에 JWT를 저장하고, HttpOnly
, secure
, SameSite
옵션을 적용
JWT가 탈취 당한다면?
JWT가 탈취되면 서버는 탈취당한 사실을 알 수 없으므로 보안을 강화하기 위해 Access Token과 Refresh Token을 나누어 사용합니다.
- Access Token의 유효기간을 짧게 설정해 토큰이 탈취돼도 금방 만료되도록 처리합니다.
- 하지만 이는 사용자 측면에서 불편하므로, Refresh Token을 활용해 재발급 받을 수 있도록 합니다.
Refresh Token 까지 탈취당한다면?
- Refresh Token Rotation을 활용하여 문제를 해결합니다.
- Access Token을 재발급 받을 때 Refresh Token도 재발급됩니다.
즉, Refresh Token을 일회용으로 사용하도록 구현합니다.
만약 탈취범이 먼저 재발급을 받아버린다면?
- 토큰 탈취범이 정상 유저보다 먼저 재발급을 받으면, AT와 RT는 새로운 토큰으로 갱신되고, 저장소에는 탈취범의 Refresh Token만 남게 됩니다.
- 정상 유저가 재발급을 받으면, Redis 서버에 탈취범의 RT만 남아 있기 때문에 정상 유저는 재발급을 받을 수 없습니다.
- 정상 유저는 다시 로그인을 통해 Refresh Token을 발급받게 되며, 이로 인해 한 명의 사용자에 대해 여러 개의 Refresh Token이 생성됩니다.
Redis의 Key : Value
쌍을 RT : UserPK
가 아닌 UserPk : RT
로 설정하여 Redis 서버에 한 명의 사용자에 대해 하나의 토큰만 존재하도록 강제합니다.
참고 자료
'Spring 단기심화 2기' 카테고리의 다른 글
TIL_저장 프로시저_241123 (1) | 2024.11.23 |
---|---|
TIL_Transaction_241122 (0) | 2024.11.22 |
TIL_람다와스트림_241119 (0) | 2024.11.19 |
TIL_Spring 예외 처리_241115 (2) | 2024.11.15 |
TIL_MSA 들어가기_241114 (0) | 2024.11.14 |