앵하니의 더 나은 보안
JWT 본문
JWT는 json web token 약자로 보통 사용자 식별에 사용되는 세션의 대체용으로 사용된다.
클라이언트가 보낸 토큰 값을 서버에서 검증하는 방식을 사용해 세션과 같이 서버 저장 자원을 사용하지 않는다.
그래서 하나의 웹 서버에서 사용자를 식별할 땐 세션을 사용하면 되지만,
프론트 엔드 서버와 API 서버를 별개로 둔 경우에는 토큰을 사용해 사용자를 식별하는 편이다.
세션으로 관리하면 서버의 자원이 2배로 사용되고 유연성이 떨어지기 때문에 토큰을 사용하는게 합리적이다.
JWT의 구조는 각각 header.payload.signature로 이루어져있으며
각 데이터는 base64 인코딩 된 상태로 데이터를 송수신한다.
header : payload를 어떤 방식으로 암호화하여 signature값을 생성할지 명시
payload : 실제 데이터들을 포함하는 데이터 영역
signature : payload를 header에 적힌 암호화 알고리즘을 기반으로 암호화한 데이터
처음 JWT 구조를 모를땐 payload 값 변경으로 쉽게 사용자 인증 우회가 가능할것이라 생각했지만
막상 서버에선 signature 값과 수신한 payload의 암호화 값을 대조하여
payload 값 변조에 대한 무결성을 선검증하므로 쉽게 변조할 수 없다.
과정을 설명하자면 아래와 같다.
- 타사용자의 권한을 사용하기 위해 payload를 변조하여 JWT 생성 후 웹 서버로 송신
- 웹 서버에서는 수신한 JWT의 무결성을 검증하기위해 signature를 생성한 방식과 동일한 암호화 알고리즘을 사용해 payload 암호화
- payload의 암호화 값과 signature의 값이 서로 다를 경우 해당 프로세스 드랍
그럼 signature 값을 payload랑 같은내용으로 암호화 시켜 보내면 되잖아?
라고 반문할 수 있지만 signature 안에는 payload 뿐만 아니라 서버에서 설정한 비밀키 또한 존재한다.
그리고 해당 암호화 값은 복호화가 가능한 알고리즘과 복호화가 불가능한 해쉬 알고리즘을 복합적으로 사용하기 때문에 signature에서 암호화 키를 뽑아 낼 수도 없다.
그래서 만약 payload를 변조하면서 그에 맞는 signature 값을 보내고자 한다면, signature에 포함된 암호화 키를 추측하거나, 또 다른 제 3의 경로로 암호화 키를 취득해야만 한다.
그리고 토큰은 사용자의 statement를 확인할 수 없기 때문에 만약 전자금융 서비스에서 사용한다면,
반드시 payload에 timestamp로 시작시간 또는 종료시간 또는 둘 다 기재해 타임아웃 기능을 구현해야한다.
토큰을 사용해 사용자를 식별하는 웹 서비스의 경우 통상적으로 세션타임아웃 기능을 고려하지 않는다.
그래서 JWT를 사용하지만, 세션타임아웃 기능이 존재하지 않을 경우
발행된 토큰의 만료시간(payload의 ext)을 지정하라고 조치 가이드를 전달하면 된다.
사실 세션이 아니라 토큰을 사용하니까 세션타임아웃 항목은 N/A가 맞다.
근데 타임아웃 기능이 있으면 보안담당자 입장에선 좀 더 무결해지니 좋지 뭐
혹시나 JWT 토큰 안에 사용자의 주요 개인 정보들이 포함 돼 있을 수도 있으니
base64 디코딩 정도는 해서 확인해보는게 좋다.
'보안 기술 > WEB' 카테고리의 다른 글
CSRF 취약점과 대응방안 (0) | 2022.08.22 |
---|---|
SSL strip과 HSTS (0) | 2022.08.12 |
WEB Ahnlab Safe Transaction bypass (20) | 2022.08.12 |
X-XSS-PROTECTION bypass(X-XSS-Nightmare, XXN) (0) | 2022.07.18 |
[CVE-2009-3555] 금취평 취약한 https 재협상 허용 관련 (0) | 2022.07.18 |