본문으로 건너뛰기

51. JWT 보안 취약점: 흔한 실수와 익스플로잇 기법

JWT(JSON Web Token)는 현대 웹 애플리케이션 어디에나 있다. 편리하고 무상태적이며 구현하기 쉽다 — 바로 그래서 잘못 구현되는 경우가 많다. CTF와 실제 애플리케이션에서 자주 만나는 JWT 취약점을 알아보자.

JWT는 왜 취약할까?​

JWT는 헤더, 페이로드, 서명 세 부분으로 구성된다. 헤더와 페이로드는 base64로 인코딩된 JSON이고, 서명은 토큰의 무결성을 검증한다. 문제는? 개발자들이 헤더를 너무 신뢰하거나 서명을 잘못 검증하는 경우가 많다는 것이다.

None 알고리즘 공격​

가장 유명한 JWT 취약점은 "none" 알고리즘 공격이다. 일부 JWT 라이브러리는 알고리즘을 "none"으로 설정할 수 있어, 사실상 서명 검증을 비활성화할 수 있다.

작동 원리:

  1. JWT 헤더와 페이로드를 디코딩
  2. 페이로드 수정 (사용자 ID 변경, 권한 상승)
  3. 헤더의 알고리즘을 "none"으로 설정
  4. 서명 제거
  5. base64로 인코딩하고 연결

CTF 문제에서는 이렇게 생겼다:

eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ1c2VyIjoiYWRtaW4ifQ.

마지막 점(.) 뒤에 서명이 없다는 걸 주목하라. 이게 단서다.

알고리즘 혼동: HS256 vs RS256​

HS256(대칭)과 RS256(비대칭) 알고리즘의 차이를 이용하는 고전적인 취약점이다.

공격 방법:

  • 서버가 RS256 (공개키/개인키 쌍) 사용
  • 공격자가 알고리즘을 HS256으로 변경
  • 서버가 공개키를 HMAC 시크릿으로 사용해 검증
  • 공격자가 공개키로 토큰 서명 (공개키는 말 그대로 공개되어 있으니까)

서버가 허용할 알고리즘을 제대로 강제하지 않는다면, 공개키를 HMAC 시크릿으로 쓰도록 속일 수 있다.

약한 시크릿 키​

많은 개발자들이 JWT 서명에 취약한 시크릿을 사용한다. jwt_tool이나 hashcat 같은 도구로 딕셔너리 공격이나 브루트포스로 크래킹할 수 있다.

자주 쓰이는 약한 시크릿:

  • "secret"
  • "password"
  • 빈 문자열
  • 짧은 숫자 코드

CTF에서는 항상 JWT 서명 크래킹을 먼저 시도해보라. 의도된 풀이인 경우가 많다.

JKU/JWKS를 통한 키 주입​

일부 JWT는 jku (JWK Set URL) 또는 jwks (내장 JWK) 헤더 파라미터를 사용해 검증 키를 어디서 가져올지 지정한다. 애플리케이션이 소스를 검증하지 않으면:

  1. 자신의 JWK Set 생성
  2. 본인 서버에 호스팅
  3. JWT 헤더가 악성 JWK URL을 가리키도록 수정
  4. 개인키로 토큰 서명
  5. 서버가 내 키를 가져와 위조된 토큰 검증

JWT 테스트 실전 도구​

jwt_tool: JWT 테스팅의 만능 도구. 자동 스캔, 토큰 조작, 크래킹 모두 가능하다.

python3 jwt_tool.py <JWT> -M at # 전체 테스트 모드
python3 jwt_tool.py <JWT> -C -d wordlist.txt # 크래킹

Burp Suite JWT Editor: 웹 앱 테스트 중 JWT를 실시간으로 조작하는 브라우저 확장.

hashcat: JWT 시크릿 오프라인 크래킹용.

hashcat -a 0 -m 16500 jwt.txt wordlist.txt

탐지와 방어​

방어자를 위해:

  • 알고리즘을 명시적으로 검증하라 — 헤더를 절대 신뢰하지 마라
  • 강하고 무작위한 시크릿 사용 (HS256 기준 최소 256비트)
  • "none" 알고리즘 비활성화
  • JKU/JWKS 소스를 화이트리스트로 검증
  • 짧은 만료 시간 고려
  • 페이로드에 민감한 데이터 저장 금지 (그냥 base64니까!)

버그 헌터를 위해:

  • 알고리즘 혼동 취약점 확인
  • 일반적인 단어 목록으로 시크릿 크래킹 시도
  • JKU/JWKS 조작 가능성 탐색
  • 만료 검증 누락 테스트
  • none 알고리즘 시도 (아직 먹히는 경우도 있다!)

마치며​

JWT는 잘못 구현될 때 강력하면서도 위험하다. CTF 문제를 풀든 보안 평가를 하든, 이 취약점들을 이해하면 큰 이점을 얻을 수 있다. 핵심은 JWT 헤더가 사용자 제어 데이터라는 것 — 그리고 사용자 제어 데이터는 절대 신뢰해선 안 된다.

해피 해킹! 🥞