해당 포스트는 아래의 영상을 참고하여 작성하였다. 👉 영상 보러가기
1. 서명 알고리즘 변조 공격 (alg:none 공격)
JWT는 일반적으로 서명을 통해 데이터의 무결성을 보장한다. 하지만 알고리즘을 none으로 설정하면 서명이 없으므로, 클라이언트가 토큰 내용을 언제든지 조작할 수 있다. 일부 서버나 라이브러리는 JWT의 서명 알고리즘으로 none을 허용할 수 있어 매우 위험한 방식이다.
따라서 이를 위한 방안으로
- 강력한 서명 알고리즘 사용: JWT를 사용할 때는 반드시 HMAC SHA 알고리즘(예: HS256)이나 RSA 알고리즘(예: RS256)과 같은 강력한 서명 알고리즘을 사용해야한다.
- 토큰 검증 구현: 서버는 수신한 JWT의 서명을 항상 검증해서 유효하지 않거나 변조된 토큰을 차단할 수 있다.
- 토큰 만료 설정: JWT에 만료 시간을 설정하여, 오래된 토큰이 사용되지 않도록 해야 한다.
2. 쉬운 디코딩
JWT는 디코딩이 매우 쉽다. 따라서 토큰 페이로드에 암호화되지 않은 민감 정보를 포함시키면 정보 유출 위험이 있다.
따라서 이를 예방하기 위해
- 민감한 정보 포함 금지: JWT에 민감한 정보를 포함하지 않는 것이 중요하다. 예를 들어, 사용자 비밀번호나 개인 식별 정보를 넣지 말아야 한다.
- 비밀 키 관리: JWT 서명에 사용되는 비밀 키를 안전하게 관리해야 한다. 키가 유출되면 공격자가 쉽게 디코딩할 수 있으니, 키를 안전한 장소에 보관하고 정기적으로 변경하는 것이 필요하다.
- 토큰 암호화: JWT를 단순히 서명하는 것 외에도 암호화하여 내용을 숨길 수 있는데, JWE(JSON Web Encryption)를 사용하면 데이터를 안전하게 보호할 수 있다.
3. 예측가능한 시크릿 키 문제
시크릿 키는 JWT의 서명을 생성하고 검증하는 데 중요한 역할을 하며, 키가 약하거나 쉽게 추측 가능하면 보안에 큰 위협이 될 수 있다. 일부 개발자들은 간단하고 짧은 키를 사용하게 되는데, 이런 키는 쉽게 추측될 수 있다. 예를 들어, "123456"이나 "password" 같은 키는 공격자가 쉽게 알아낼 수 있다. 만약 키가 코드에 하드코딩되어 있다면, 코드가 유출될 경우 공격자는 이 키를 이용해 JWT를 위조할 수 있다.
따라서 이를 예방하기 위해
- 강력한 키 생성: 최소 32자리 이상의 복잡한 문자열을 사용하고, 대문자, 소문자, 숫자, 특수문자를 혼합하여 사용하는 것이 좋다.
- 키 관리 시스템 사용: 클라우드 서비스나 전문 키 관리 시스템을 이용하여 키를 안전하게 관리하는 것이 중요하다.
- 정기적인 키 변경: 주기적으로 시크릿 키를 변경하여 보안을 강화하고, 키가 유출되었을 경우의 위험을 줄여야 한다.
- 환경 변수 사용: 키를 하드코딩하지 않고, 환경 변수나 안전한 저장소에서 불러오는 방식을 사용하는 것이 좋다.