블로그
home
Nation-State Cyber Actors Analysis Report
home

자바 인증 라이브러리 pac4j-jwt 관리자 권한 탈취 취약점(CVE-2026-29000) 분석

작성자
이준희
감수인
작성일
2026/03/10
배포일
2026/04/16
문서등급
TLP:CLEAR
Tags
CVE-2026-29000
Java
pac4j-jwt
문서유형
TechNote

01. 취약점 개요

'26년 2월 28일, 자바(Java) 기반 JWT* 인증 라이브러리 pac4j-jwt에서 비서명 토큰(PlainJWT)**을 통한 서명 검증 로직 우회 취약점(CVE-2026-29000) 발견
* JWT(JSON Web Token) : JSON 형식의 사용자 인증 정보를 서명 및 암호화하여 토큰으로 전달하는 표준 방식(RFC 7519)
** PlainJWT : 토큰의 진위 여부를 검증하기 위한 서명이 존재하지 않는 토큰으로 진정성(Authenticity) 및 무결성(Integrity) 보장 불가
비서명 토큰(PlainJWT)을 서버의 공개키로 암호화하여 JWE* 토큰으로 전송할 때 toSignedJWT 메서드가 반환하는 null 값에 대한 예외 처리가 미흡하여 발생(CVSS 10.0 만점, Ver 3.x)
암호화(JWE)와 서명 검증(JWS**) 모두 구성된 환경에서 발생하며 서명 검증만 사용하는 경우 우회 불가
공격자는 Claim***이 위조된 비서명 토큰(PlainJWT)을 통해 관리자 권한까지 탈취 가능
* JWE(JSON Web Encryption) : 토큰이 서버의 공개키로 암호화되어 토큰의 기밀성(Confidentiality) 보장
** JWS(JSON Web Signature) : 토큰의 진위 여부를 검증할 수 있는 서명을 통해 토큰의 진정성(Authenticity) 및 무결성(Integrity) 보장
*** Claim : sub(사용자 ID), role(권한), jti(토큰 ID) 등을 포함한 정보로 공격자가 위변조할 수 있기 때문에 서명 검증 필요

02. 영향받는 버전 및 대응방안

암호화(JWE) 및 서명(JWS)을 모두 사용하는 4.5.9, 5.7.9, 6.3.3 버전 미만의 pac4j-jwt 인증 라이브러리가 영향을 받으며, 해당 라이브러리를 사용하는 프레임워크(Spring Boot 등)도 버전 확인 필요
Maven 버전 확인 방법 : mvn -q dependency:tree -Dincludes=org.pac4j:pac4j-jwt
Gradle 버전 확인 방법 : ./gradlew -q dependencies --configuration runtimeClasspath | grep –i "pac4j-jw“
영향받는 버전 사용 시 최신 보안패치 진행
제품명
영향받는 버전
보안패치 버전
pac4j-jwt (org.pac4j:pac4j-jwt)
4.5.9 미만
4.5.9
5.7.9 미만
5.7.9
6.3.3 미만
6.3.3

03. CVE-2026-29000 취약점 상세 분석

3.1. 취약점 분석

암호화(JWE) 및 서명 검증(JWS)이 모두 구성된 취약한 버전의 pac4j-jwt 환경에서 복호화된 JWE 토큰의 페이로드가 비서명 토큰(PlainJWT)일 때 인증 우회 취약점 발생
비서명 토큰(PlainJWT)을 서버 공개키로 암호화한 JWE 토큰이 JwtAuthenticator.java 코드에 입력될 때 toSignedJWT 메서드가 반환하는 null 값에 대한 예외 처리가 미흡하여 서명 검증 로직 자체가 우회
단계
정상 흐름
공격 흐름
① JWE 수신
JWS를 암호화한 JWE 수신
PlainJWT를 암호화한 JWE 수신
② JWE 복호화
JWE 복호화
JWE 복호화
③ JWS 추출
toSignedJWT 메서드 JWS 반환 signedJWT = JWS 할당
toSignedJWT 메서드 null 반환 signedJWT = null 할당
④ 서명 검증
if (signedJWT != null)가 True로 서명 검증 진행
if (signedJWT != null)가 False로 서명 검증 미진행
⑤ 프로필 생성
검증된 Claim으로 프로필 생성
검증되지 않은 Claim으로 프로필 생성
취약한 버전(6.3.2)의 JwtAuthenticator.java 코드 분석을 통해 서명 검증 로직 확인
※ pac4j-jwt 6.3.2 버전의 GitHub 사이트 : https://github.com/pac4j/pac4j/tree/pac4j-parent-6.3.2/pac4j-jwt
JwtAuthenticator.java 파일 197번 라인 : 암호화되어 있는 JWE를 복호화
JwtAuthenticator.java 파일 198번 라인 : toSignedJWT 메서드는 Nimbus JOSE+JWT* 라이브러리 메서드로 서명 토큰(JWS, SignedJWT)이 입력되면 JWS 객체를 반환하고 비서명 토큰(PlainJWT)이 입력되면 null 값을 반환
* Nimbus JOSE+JWT : JOSE(JavaScript Object Signing and Encryption) 표준을 Java로 구현한 라이브러리
JwtAuthenticator.java 파일 215번 라인 : signedJWT 변수에 null 값이 할당되면 서명 검증 로직 전체가 무시되어 토큰의 위변조 여부를 검증하지 않고 무조건 신뢰
JwtAuthenticator.java 파일 244번 라인 : PlainJWT 토큰에 포함된 Claim 정보를 인증된 것으로 간주하고 createJwtProfile 함수를 호출하여 Claim에서 요구한 관리자 권한 등을 공격자에게 부여
취약한 버전의 JwtAuthenticator.java 파일 중 일부
패치된 버전(6.3.3)의 JwtAuthenticator.java 코드에서는 서명 검증 로직에서 예외 처리
※ pac4j-jwt 6.3.3 버전의 GitHub 사이트 : https://github.com/pac4j/pac4j/tree/pac4j-parent-6.3.3/pac4j-jwt
signedJWT 변수에 null 값 할당 시 CredentialsException을 호출하여 예외 처리
패치된 버전의 JwtAuthenticator.java 파일 중 일부

3.2. 취약점 PoC

PoC는 Ubuntu(22.04.5), Java(17.0.18), Maven(3.6.3), pac4j-jwt(6.0.3 및 6.3.3) 환경에서 진행하며 별도의 웹 서버를 구축하지 않고 자바 코드를 프로세스로 직접 실행
※ PoC 코드 사이트 : https://github.com/kernelzeroday/CVE-2026-29000/tree/main/poc
공격자는 비서명 토큰(PlainJWT)를 JWE로 암호화하기 위해 서버 공개키가 필요하며 일반적으로 JWKS* 앤드포인트(/.well-known/jwks.json), TLS 인증서, 앱 설정 파일, 공개 코드 저장소 등에서 쉽게 수집할 수 있기 때문에 공격자가 공개키를 이미 확보했다고 가정하고 Poc.java 파일에서 공개키를 직접 생성하여 진행
* JWKS(JSON Web Key Set) : 공개키를 JSON 형식으로 표현한 표준(RFC 7517)으로 프레임워크에서 주로 사용
서버 공개키 확인 예시(/.well-known/jwks.json)
Maven 파일(pom.xml)에서 pac4j-jwt 인증 라이브러리를 취약한 버전(6.0.3)으로 설정 후 Poc.java 실행
pom.xml 파일 19번 라인 : pom.xml에서 취약한 버전(6.0.3)으로 설정된 pac4j-jwt 확인
취약한 버전을 사용하는 pom.xml 파일
Poc.java 파일 28~34번 라인 : 인가받지 않은 관리자 권한을 변수로 선언 및 할당
Poc.java 파일 72, 73번 라인 : 인가받지 않은 관리자 권한을 Claim으로 할당
Poc.java 파일 77번 라인 : 서명이 존재하지 않는 비서명 토큰(PlainJWT)을 생성
Poc.java 파일 84번 라인 : 비서명 토큰(PlainJWT)을 수집한 서버 공개키로 암호화하여 JWE 생성
Poc.java 파일 중 일부
취약한 버전(6.0.3)으로 설정된 pac4j-jwt 라이브러리 환경에서는 관리자 권한 탈취 가능
관리자 권한 탈취
pac4j-jwt 버전을 6.3.3으로 적용하면 "A non-signed JWT cannot be accepted ..." 경고 문구와 함께 비서명 토큰(PlainJWT)을 암호화한 JWE는 거부
패치된 버전을 사용하는 pom.xml 파일
관리자 권한 탈취 불가

04. 취약점 타임라인

일자
주요내용
비고
2026-02-28
• CodeAnt AI 코드 검토기가 취약점 발견, PoC 검증 • Jérôme Leleu(pac4j 관리자)에게 비공개 정보 전송
https://www.codeant.ai/security-research/pac4j-jwt-authentication-bypass-public-key
2026-03-02
• 4.x, 5.x, 6.x 버전용 패치 배포
https://github.com/pac4j/pac4j/tree/pac4j-4.5.9 https://github.com/pac4j/pac4j/tree/pac4j-parent-5.7.9 https://github.com/pac4j/pac4j/tree/pac4j-parent-6.3.3
2026-03-02
• pac4j에서 보안 권고문 발표
https://www.pac4j.org/blog/security-advisory-pac4j-jwt-jwtauthenticator.html
2026-03-03
• VulnCheck에서 CVE-2026-29000 지정
https://www.vulncheck.com/advisories/pac4j-jwt-jwtauthenticator-authentication-bypass

05. 참고자료

1.
CVE-2026-29000: Critical Authentication Bypass in pac4j-jwt - Using Only a Public Key (CVSS 10) : https://www.codeant.ai/security-research/pac4j-jwt-authentication-bypass-public-key
2.
CVE-2026-29000: pac4j-jwt JwtAuthenticator authentication bypass : https://github.com/kernelzeroday/CVE-2026-29000/tree/main/poc
3.
Security advisory for pac4j-jwt (JwtAuthenticator) : https://www.pac4j.org/blog/security-advisory-pac4j-jwt-jwtauthenticator.html
IGLOO Corp. 2026. All rights reserved.