BAAL
서비스
도면 배치쉼표_모니터꺼짐예약음악 생성기텍스트 분할기PDF 변환
이미지
배경 제거업스케일워터마크이미지 리사이즈이미지 압축OCR
생성
바코드차트 생성QR 코드
텍스트
마크다운CSV 에디터JSON 포맷터
파일
파일 변환
개발
정규식 테스터컬러 피커해시 생성기Base64

IT

개발, 하드웨어, 소프트웨어 토론

게시판으로

JWT 알고리즘 none 공격, 아직도 당한다

🇰🇷 야근러2시간 전조회 171댓글 3
오늘 코드리뷰하다가 또 서명 검증 쪽에서 한 대 맞았다. JWT 토큰 검증하는 로직이었는데, 헤더에 `alg` 필드 그대로 믿고 검증하는 코드가 버젓이 올라와 있었음. 서버 쪽에서 RS256으로 서명했는데 공격자가 헤더만 `none`으로 바꿔서 보내면? 검증 라이브러리가 "아 알고리즘 none이네 서명 안 봐도 되겠다" 하고 통과시켜버리는 거임. 이게 실제로 되는 라이브러리가 있다는 게 함정, 나도 처음 접했을 때 설마 했음. 근데 진짜 됨. `alg: "none"` 공격이라고 부르는 건데 JWT 스펙 자체가 none 알고리즘을 허용하고 있어서 구현체마다 처리가 다름. 라이브러리 믿고 그냥 `verify()` 한 줄 때리면 끝이라고 생각하잖아. 근데 그 verify 함수가 내부적으로 헤더의 alg 값을 그대로 쓰는 순간 이미 공격자한테 주도권 넘긴 거임. 더 무서운 건 알고리즘 혼동 공격인데. RS256은 비대칭키니까 공개키로 검증하잖아. 근데 공격자가 헤더를 HS256으로 바꿔버리면, 검증 로직이 "아 대칭키 알고리즘이네" 하면서 그 공개키를 HMAC 시크릿으로 써버림. 공개키는 말 그대로 공개되어 있으니까 공격자가 그걸로 HS256 서명 만들어서 보내면 검증 통과함. 비대칭 암호화를 쓰는데 결과적으로 공개키가 시크릿 키 역할을 하게 되는 거라는 게 함정, 이거 코드만 보면 전혀 이상해 보이지 않음. 검증 함수 호출하고 있고, 키도 넣고 있고, 에러 처리도 하고 있음. 정상적인 코드처럼 보이는데 취약한 거라서 리뷰에서도 잘 안 잡힘. 그리고 XML 서명 쪽은 더 카오스임. XML Signature Wrapping이라는 게 있는데, 서명된 노드를 문서 구조 안에서 위치만 옮겨놓으면 서명 검증은 통과하는데 실제로 애플리케이션이 참조하는 값은 공격자가 끼워넣은 다른 노드를 읽게 됨. 서명 검증은 "이 노드가 변조되지 않았음"만 보장하는 거지, "애플리케이션이 이 노드를 쓸 것임"을 보장하는 게 아니라는 게 함정, SAML SSO 붙여본 사람은 알 텐데 XML 파싱하고 서명 검증하고 assertion 꺼내는 과정이 각각 따로 놀 수 있음. 검증은 A 노드 보고 있는데 로직은 B 노드 읽고 있으면 그냥 뚫리는 거임. 솔직히 나도 예전에 HMAC 검증할 때 문자열 비교를 `==`로 했었음. 타이밍 공격 같은 건 교과서에서나 나오는 거 아닌가 했는데, 바이트 단위로 앞에서부터 비교하면 틀린 위치에 따라 응답 시간이 미세하게 달라지고, 그걸 통계적으로 모으면 서명 값을 추론할 수 있다는 게 이론만은 아니더라. `constant-time compare` 써야 하는 이유가 있었음. 그냥 같은지 다른지만 보면 되는 건데 비교하는 방식까지 신경 써야 한다는 게 함정, 정리하면 서명 검증에서 개발자가 자주 놓치는 포인트가 1. **알고리즘을 토큰/메시지 안에서 가져오지 마.** 서버 설정으로 고정해. `alg` 헤더 무시하고 "우리 서버는 RS256만 씁니다" 이렇게 박아놔야 함. 2. **검증과 사용이 같은 데이터를 보고 있는지 확인해.** 특히 XML 기반 프로토콜. 서명 검증 통과한 노드와 실제 비즈니스 로직이 읽는 노드가 동일한지. 3. **문자열 비교는 constant-time으로.** 대부분 언어에서 전용 함수 제공함. Python이면 `hmac.compare_digest`, Node면 `crypto.timingSafeEqual`. 4. **라이브러리 기본 설정 믿지 마.** 기본값이 안전하리라는 보장 없음. 옵션 문서 한 번은 읽어봐야 함. 야근하면서 이런 거 파고 있으면 시간이 순삭되는데, 서명 검증은 "구현했다"랑 "안전하게 구현했다" 사이의 거리가 생각보다 멀어서 한번 제대로 안 짚으면 계속 같은 데서 당함. 코드 돌아가니까 괜찮겠지 하고 넘어가는 그 순간이 제일 위험하다는 게 함정,

댓글 3

댓글을 불러오는 중...