XML 서명 래핑 공격을 막는 안전한 SAML 검증
초록
본 논문은 SAML 어설션 검증 시 XML 서명 래핑 공격에 취약한 구현 사례를 분석하고, 잘못된 라이브러리 문서와 샘플 코드가 보안 결함을 초래하는 메커니즘을 밝힌다. 저자는 안전한 검증 절차와 올바른 API 사용법을 제시함으로써 개발자가 실수 없이 SAML 서명을 검증하도록 가이드한다.
상세 분석
SAML(Security Assertion Markup Language)은 인증·인가 정보를 교환하기 위한 표준 XML 포맷이며, 대부분의 기업 환경에서 SSO(Single Sign‑On) 구현에 활용된다. 그러나 SAML 어설션은 XML 디지털 서명으로 무결성을 보장하므로, 검증 로직이 정확히 구현되지 않으면 “XML Signature Wrapping”(XML 서명 래핑) 공격에 노출된다. 이 공격은 공격자가 서명된 요소를 그대로 두고, 동일한 문서 내에 새로운 악의적 요소를 삽입하거나 기존 요소를 복제·재배치함으로써 검증 로직이 원본 어설션이 아닌 변조된 데이터를 사용하도록 만든다.
Somorovsky 등은 기존 SAML 검증 프레임워크가 XPath 기반 선택자를 사용할 때, 네임스페이스 처리 오류나 “first‑node” 선택 로직이 잘못 구현돼 공격자가 삽입한 요소가 먼저 선택되는 상황을 발견했다. 논문은 특히 Java용 Apache Santuario, OpenSAML, 그리고 .NET의 System.Security.Cryptography.Xml 라이브러리에서 흔히 보이는 패턴을 지적한다.
첫 번째 문제는 “Document.getElementsByTagName”과 같은 DOM 메서드가 전체 문서에서 동일한 로컬 이름을 가진 모든 요소를 반환한다는 점이다. 검증 코드는 종종 첫 번째 반환 요소만 검증하고, 실제로는 서명된 요소가 아닌 공격자가 삽입한 요소가 첫 번째 위치에 있을 경우 검증을 통과한다. 두 번째 문제는 “XPathExpression.evaluate” 시에 “namespace‑aware” 옵션을 비활성화하거나, “//Signature”와 같은 절대 경로 대신 상대 경로를 사용함으로써 의도치 않은 노드가 선택되는 상황이다.
또한, 라이브러리 문서가 “Signature.validate” 메서드만 호출하면 충분하다고 오해하게 만들며, 실제로는 서명 검증 전후에 “Reference” 객체가 가리키는 URI와 실제 어설션 내용이 일치하는지 확인해야 한다는 점을 간과한다. 논문은 이러한 문서상의 모호함이 개발자에게 “검증이 자동으로 수행된다”는 잘못된 믿음을 심어, 보안 검증 단계가 생략되거나 축소되는 원인이 됨을 강조한다.
저자는 안전한 구현을 위해 다음과 같은 원칙을 제시한다. 1) 서명된 “Reference”가 정확히 기대하는 ID(예: AssertionID)와 매핑되는지 명시적으로 확인한다. 2) XPath를 사용할 경우 반드시 “NamespaceContext”를 제공하고, “//Signature” 대신 “/samlp:Response/saml:Assertion/ds:Signature”와 같이 절대 경로와 네임스페이스 프리픽스를 명시한다. 3) DOM 탐색 시 “getElementsByTagNameNS”와 같이 네임스페이스를 고려한 메서드를 사용하고, 반환된 노드 리스트를 순회하며 ID 매칭을 검증한다. 4) 라이브러리의 “secure validation” 플래그(예: XMLSignatureFactory.setFeature(“org.apache.jcp.xml.dsig.secureValidation”, true))를 활성화한다. 5) 외부 엔티티(XXE)와 같은 부가적인 XML 파싱 위험을 차단하기 위해 파서 설정을 강화한다.
이러한 방식을 적용한 샘플 코드는 기존 예제와 비교해 30% 정도의 라인 수가 증가하지만, 보안 취약점을 완전히 차단한다는 점에서 충분히 가치가 있다. 또한, 저자는 오픈소스 프로젝트에 PR을 제출해 문서와 예제 코드를 업데이트함으로써 커뮤니티 차원의 방어 체계를 강화했다.
댓글 및 학술 토론
Loading comments...
의견 남기기