231023 TIL #223 JWT의 구조와 취약점

김춘복·2023년 10월 23일
0

TIL : Today I Learned

목록 보기
223/336

Today I Learned

유튜브 알고리즘에 뜬 영상을 보다가 코딩애플님의 JWT 영상을 보고 구조와 취약점에 대해 좀 더 자세히 공부해보았다. 항해99에서 가르쳐준 대로만 적용을 했기 때문에 별 고민 없이 사용했는데 보안쪽으로 중요한 요소라 좀 더 공부를 해봐야 할 것 같다.


JWT

Json Web Token. 유저를 인증하고 식별하기 위한 토큰 기반 인증.

  • 토큰 자체에 사용자의 권한 정보나 서비스 정보가 포함된다.

  • RESTful과 같은 Stateless 환경에서 사용자 데이터를 주고받을 수 있다.

구조

  1. Header
    JWT에서 사용하는 타입(typ)과 서명 생성에 사용된 해시 알고리즘(alg)의 종류가 담겨져 있다.
{
  "typ": "JWT",
  "alg": "HS256"
}
  1. Payload
    Claim이라는 사용자에 대한 property를 key-value 형태로 저장한다.
    어떤 Claim을 넣을 지는 개발자의 선택에 달려있다.
    아래의 표준 스펙들이 흔히 사용되지만 빼도 되고, 다른 claim을 넣어도 된다.
  • 표준 스펙상 사용되는 Claim들

    iss : 토큰발급자
    sub : 토큰 제목
    aud : 토큰 대상자
    exp : 토큰 만료 시간
    nbf : 토큰 활성 날짜 (이 이전 토큰은 활성화되지 않음을 보장한다)
    iat : 토큰 발급 시간
    jti : 토큰 식별자 (issuer가 여러명일때 구분을 위함)

가장 중요한 것은 민감한 정보는 담지 않아야 한다.
특별한 암호화가 되어있지 않기 때문에 누구나 디코딩이 가능해 payload에 담긴 내용을 볼 수 있다. 그러므로 단순 식별 정보만 담아야 한다.

  1. Signature
    가장 중요한 부분으로 헤더와 페이로드를 합친 후 서버에서 지정한 secret key(개인키)로 암호화 시켜 토큰을 변조하기 어렵게한다.
    즉, Signature 부분은 서버에 있는 키로만 복호화가 되므로 다른 클라이언트들이 임의로 복호화 혹은 조작이 불가능하다.
    만약 누군가 payload를 변조해서 jwt를 요청한다 해도 Signature가 다르기 때문에 secret key를 모르면 변조가 불가능하다.

취약점

출처는 코딩애플

  • 일단 JWT 토큰은 쿠키-세션에 비해 가지고 있는 정보다 많다. 세션은 세션 저장소에서 세션ID로 클라이언트의 정보를 계속 찾아봐야 하는데 JWT는 토큰만 있으면 통과를 시켜준다. 그래서 이용자가 많으면 JWT가 성능에서 유리하다.

  • 하지만 이런 점 때문에 JWT는 여러 취약점이 존재한다.

  1. JWT 토큰은 디코딩이 쉬우니 개인정보를 최소한만 담고 있게 해야한다.

  2. alg(암호화 알고리즘)을 HS256을 쓰는 것이 일반적이지만 none으로 만들게 될 경우 취약점이 발생한다. 가끔 none으로 공격이 들어오니 이때 거절을 할 수 있게 해야한다.

  3. 시크릿키를 짧고 간단한 문자열로 만들면 안된다.
    키를 매우 길게 쓰고 공유를 금지하던가, 생성용키/검증용키 2개로 나눠서 쓰면 좋다.

  4. JWT는 누가 중간에 탈취해도 stateless하기 때문에 구조상 탈취된 토큰을 정지할 수 없다.
    탈취하기 어려운 저장소(httpOnly cookie)에 저장해 훔치기 어렵게 하거나
    JWT 유효기간을 5분정도로 매우 짧게 만들면 된다.
    Refresh Token을 쓰면 토큰의 유효기간을 짧게 만들어서 자주 발급하게하는게 가능하다.
    Refresh Token Rotation(Refresh Token을 1회용으로 만듬)을 활용한다.
    더 자세한 내용은 추후 Refresh Token에 대해서 정리해보려한다.

profile
꾸준히 성장하기 위해 매일 log를 남깁니다!

0개의 댓글