최근에 키클락에 어떤 취약점이 있는지 그냥 궁금해서 검색해봤다.
2024년 9월에 나온 취약점이다
간단하게 SAML 서명 검증을 우회해버리는 취약점이다..
그냥 SSO 시스템을 뚫어버리는 엄청난 취약점..
취약점 분석
안랩
https://asec.ahnlab.com/ko/83323/
안랩의 데이터이고 내용은
Keycloak XMLSignatureUtil 클래스 내의 SAML 서명 검증 방법에 결함이 있어 공격자가 검증을 우회할 수 있는 조작된 응답을 만들어 권한 상승 또는 사칭 공격으로 이어질 수 있는 취약점(CVE-2024-8698)
라고 한다.
깃허브를 찾아봤다.
라고 한다. 한글로 번역하자면
Keycloak XMLSignatureUtil 클래스 내의 SAML 서명 검증 방법에 결함이 있습니다. 이 방법은 서명된 요소를 지정하는 데 사용된 Reference 요소가 아니라 XML 문서에서 서명의 위치를 기반으로 SAML 서명이 전체 문서에 대한 것인지 아니면 특정 어설션에만 대한 것인지 잘못 판단합니다. 이 결함으로 인해 공격자는 검증을 우회할 수 있는 조작된 응답을 만들어 권한 상승 또는 사칭 공격으로 이어질 가능성이 있습니다.
레드햇
이건 레드햇 사이트에 있는 내용이다.
Statement에 대해 번역하면
이 취약점은 SAML 인증을 사용하는 시스템에서 권한 상승 및 사용자 사칭을 용이하게 할 수 있는 잠재력으로 인해 심각도가 높습니다. 핵심 문제는 Keycloak의 서명 검증 방법에서 부적절한 검증 논리로 인해 발생하는데, 이는 참조된 요소를 명시적으로 확인하는 대신 서명의 위치에 의존합니다. 공격자는 XML 구조를 조작하여 서명 검증을 우회하고 유효한 서명된 어설션을 유지하면서 서명되지 않은 어설션을 삽입할 수 있습니다. 이를 통해 권한이 높은 계정에 대한 무단 액세스가 허용되어 SAML 기반 ID 공급자 및 서비스 공급자에게 심각한 보안 위험이 발생합니다.
라고 한다 (구글아 번역 고마워..)
결론적으로 검증을 우회해서 Assertion 을 유지하면서 무단 액세스를 할수있다는 내용이다.
내가 코드분석 해보기
그래서 궁금해서 코드를 살펴보았다.
DocumentUtil.getDirectChildElement 메소드에 취약점이 있었다.
여기서 TargetNamespace,targetLocalName 에 대한 입력값에 취약점이 있었던것 같다.
새로 추가된 함수에서 입력값을 if 문을 통해 검증해서 취약점을 보완한것같다.
/**
* Returns the element that contains the signature for the passed element.
*
* @param element The element to search for the signature
* @return The signature element or null
*/
public static Element getSignature(Element element) {
Document doc = element.getOwnerDocument();
NodeList nl = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
if (element.getAttributeNode(JBossSAMLConstants.ID.get()) != null) {
// set the saml ID to be found
element.setIdAttribute(JBossSAMLConstants.ID.get(), true);
}
KeySelector nullSelector = new KeySelector() {
@Override
public KeySelectorResult select(KeyInfo ki, KeySelector.Purpose prps, AlgorithmMethod am, XMLCryptoContext xmlcc) throws KeySelectorException {
return () -> null;
}
};
try {
for (int i = 0; i < nl.getLength(); i++) {
Element signatureElement = (Element) nl.item(i);
DOMValidateContext valContext = new DOMValidateContext(nullSelector, signatureElement);
DOMStructure structure = new DOMStructure(signatureElement);
XMLSignature signature = fac.unmarshalXMLSignature(structure);
for (Reference ref : (List<Reference>) signature.getSignedInfo().getReferences()) {
try {
Data data = fac.getURIDereferencer().dereference(ref, valContext);
if (data instanceof NodeSetData) {
Iterator<Node> it = ((NodeSetData) data).iterator();
if (it.hasNext() && element.equals(it.next())) {
return signatureElement;
}
}
} catch (URIReferenceException e) {
logger.trace("Invalid URI reference in signature " + ref.getURI());
}
}
}
} catch (MarshalException e) {
logger.trace("Error unmarshalling signature", e);
}
return null;
}
GPT 한테 분석 부탁하기
Keycloak의 XMLSignatureUtil 클래스에서 변경된 부분은 SAML 서명 검증의 정확성과 보안을 강화하기 위해 DocumentUtil.getDirectChildElement 메서드에서 XMLSignatureUtil.getSignature 메서드로 전환된 것입니다. 이 변경사항의 목적과 차이점을 상세히 살펴보겠습니다.
1. 기존 코드 (DocumentUtil.getDirectChildElement)
작동 방식
- 이 메서드는 XML 노드 트리에서 특정 조건을 만족하는 자식 엘리먼트를 직접 탐색합니다.
- element: 부모 XML 엘리먼트입니다.
- XMLSignature.XMLNS: XML 서명 네임스페이스.
- "Signature": 검색할 태그 이름.
- 결과적으로 element의 직속 자식 노드 중 Signature 태그와 네임스페이스가 일치하는 노드를 반환합니다.
문제점
- 이 방식은 단순히 XML 구조를 탐색하여 서명을 찾기 때문에 서명 검증 과정에서 중요한 조건을 확인하지 않습니다.
- XML 서명이 어디에 위치하든 상관없이 우회 공격(ex. XML Wrapping Attack)에 취약할 수 있습니다.
- 예를 들어, 악의적인 사용자가 XML 문서의 구조를 변조하여 서명이 유효하지 않은 부분에 영향을 끼치지 않고 검증을 우회할 가능성이 있습니다.
2. 변경된 코드 (XMLSignatureUtil.getSignature)
작동 방식
- XMLSignatureUtil.getSignature는 XML 서명의 위치뿐 아니라 서명의 유효성을 더 철저히 검증합니다.
- 내부 처리 개선
- 명확한 서명 위치 확인: XML 서명이 문서 구조 상 적절한 위치에 있는지 확인합니다.
- 서명 정합성 검증: 서명된 내용이 실제로 문서와 일치하며 변조되지 않았는지 확인합니다.
- 중복 서명 방지: XML 문서에 여러 개의 서명이 포함되어 있을 경우, 가장 적절한 서명만 선택하고 검증합니다.
안전성 강화
- 이 메서드는 단순히 XML 구조를 탐색하지 않고, 서명 요소가 실제로 해당 XML 문서의 인증 데이터를 보호하는지를 확인합니다.
- XML Wrapping Attack 및 서명 검증 우회 공격 방지.
- XML 서명 표준과 Keycloak의 SAML 사양을 더 철저히 준수.
3. 주요 차이점 요약
기능기존 방식 (DocumentUtil.getDirectChildElement)변경된 방식 (XMLSignatureUtil.getSignature)
작업 방식 | 단순히 XML 노드를 탐색 | 서명 위치 및 유효성 검증 |
보안 수준 | 취약 (Wrapping Attack 가능성) | 강화 (위치, 정합성, 중복 서명 처리) |
적용 대상 | XML 구조 탐색에 의존 | SAML 표준을 준수하는 서명 검증 |
서명 검증 우회 | 가능 | 방지 |
라고한다.. GPT야 요약 고마워
느낀점
이전 버전까지 취약점이 지속적으로 있었을텐데
오픈소스는 역시 제로데이 공격에 취약하다.
오픈소스는 신중하게 써야할것 같다.
'혼자공부한거' 카테고리의 다른 글
SSO 란 무엇일까 (0) | 2024.11.22 |
---|---|
JWT 토큰 (0) | 2024.05.24 |
[스프링부트] 스프링부트 CRUD deleteMapping 사용하기 (0) | 2021.08.11 |