Skip to content

JWT 보안 모범 사례 — 토큰을 안전하게 다루는 법

JWT는 편리하지만, "토큰 하나에 모든 걸 믿는다"는 구조라서 다룰 때 실수하기 쉬워요. 잘못 쓰면 서명이 유효해도 이상한 토큰이 통과하거나, 탈취된 토큰이 오래 살아남아요. 그래서 보안 관점에서 지켜야 할 원칙을 정리해두면 운영에서 흔들리지 않아요.

개요

JWT 보안은 크게 두 축으로 나뉘어요. 토큰 자체를 안전하게 만드는 일(수명·비밀정보·알고리즘)과, 토큰을 안전하게 전달·보관·폐기하는 일(유출 시 대응)이에요. 두 축을 함께 챙겨야 실제 방어가 됩니다.

핵심 개념

수명을 짧게 잡아요. 만료(exp)를 짧게 잡을수록 탈취된 토큰이 쓸 수 있는 시간이 줄어요. 토큰이 탈취돼도 오래 못 쓰게 하는 게 가장 기본적인 방어예요.

민감 정보를 넣지 않아요. 페이로드는 암호화가 아니라 인코딩이므로 누구나 읽을 수 있어요. 비밀번호, 세션 키, 개인정보 같은 걸 넣지 않고, 필요한 값은 서버가 DB에서 다시 참조하는 편이 안전해요.

알고리즘을 고정하고 합의해요. 검증 쪽에서 토큰 헤더의 알고리즘을 그대로 믿으면 알고리즘 혼동 공격 위험이 있어요. "alg: none"은 거부하고, 발급자와 합의한 알고리즘만 허용하도록 설정해야 해요.

서명 검증만으로 "누구"를 판단하지 않아요. 서명이 유효하다는 건 "내용이 위조되지 않았다"는 뜻이지 "이 사람이 정말 그 사람이다"는 보장이 아니에요. 클레임(exp·aud·iss) 검증과 필요에 따른 추가 확인을 함께 해요.

토큰 탈취 시 대응을 설계해요. 짧은 만료로 피해를 줄이고, 필요하면 토큰 폐기(블랙리스트)버전·갱신을 둬서 탈취된 토큰을 빨리 무효화할 수 있게 해요. 이건 토큰 수명·보안 정책에 따라 설계가 달라져서 "확인 필요"인 부분이기도 해요.

전달과 보관을 안전하게. HTTPS로 전달하고, 브라우저에 둘 때는 보안 설정(예: HttpOnly 쿠키 등)을 함께 고려해요. 어디에 토큰을 두느냐(XSS·탈취 노출)까지 접근 제어 설계의 일부예요.

토큰을 로그에 남기지 않아요. 디버깅 편하자고 토큰 전체를 로그에 찍는 실수를 하기 쉬워요. 토큰이 로그·오류 보고·모니터링에 흘러들어가면 그 기록들이 곧 탈취 경로가 돼요. 토큰 원문은 로그에 남기지 않고, 필요한 경우 앞부분 일부나 해시만 쓰는 걸 원칙으로 해요.

검증 라이브러리 설정도 보안 항목이에요. JWT 라이브러리가 "허용 알고리즘", "none 차단", "만료·발급자·수신자 검증"을 어떻게 기본값으로 두는지 확인하고, 명시적으로 설정해요. 기본값에 맡기다 보면 알고리즘 혼동 공격이나 만료 미검증 같은 실수가 생길 수 있어요.

실제 적용(데이터스케쳐스)

로그인 후 받은 JWT는 짧은 만료를 기본으로 두고, 여러 제품이 같은 검증 절차를 공유하도록 설계해요. 페이로드에는 사용자 식별·만료 등 필요한 값만 넣고, 민감 데이터는 넣지 않아요. 만료된 토큰의 재사용을 막고, 의심스러운 상황에서 토큰을 빨리 무효화할 수 있는 정책을 정리해두는 게 운영의 핵심이에요.

토큰을 브라우저에 보관하는 방식이나 탈취 대응(블랙리스트)은 토큰 수명·보안 정책과 맞물려서 정답이 하나가 아니라서, 도입할 때마다 기준을 다시 확인하도록 해요.

더 알아보기