안녕하세요.
첫 보안 게시글로 OWASP TOP 10 2017 버젼에서 새로 등록된 취약점인 "XML 외부 개체(XXE)" 문제에 대해 다뤄보려고 합니다.
해당 글은 상황에 따라, 주기적으로 업데이트 됩니다.
[참조: OWASP TOP 10 2017 코리아챕터]
먼저 OWASP 에서 말하는 해당 공격의 정의는 아래와 같다.
"
오래되고 설정이 엉망인 많은 XML 프로세스들은 XML 문서내에서 외부 개체 참조를 평가합니다. 외부개체는 파일 URI 처리기, 내부 파일 공유, 내부 포트스캔, 원격 코드 실행과 서비스 거부 공격을 사용하여 내부 파일을 공개하는데 사용할 수 있습니다.
"
손쉽게 말하면,
Entity는 반복적으로 나오는 문장이나 문자열을 다른 곳에 저장해 놓고 참조하는 개체로,
재사용이 가능한 XML , DTD 등의 데이터가 될 수 있습니다. 이 중 Entity의 대상이 DTD 외부에 존재하는 경우 External Entity 라고 합니다.
이러한 External Entity( 외부 개체) 의 사용을 금지 시키지 않아 발생하는 취약점 입니다.
[참조: OWASP TOP 10 2017 코리아챕터]
xml 통신을 하는 어플리케이션에 위와같은 방법으로 공격을 수행하게 됩니다.
*추가 공격 방법은 현재 code syntax highlight가 지원이 안돼, 가독성이 떨어져 다른 방법으로 업로드 예정입니다.
보안책으로는, OWASP 에서는 아래와 같이 권고합니다.
프로그래머는, 아래와 같은 방법으로 외부개체 취약점에 대해 보완을 할 수 있습니다.
일반 가이드
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
JAVA 코드 상에서는 JAXP DocumentBuilderFactory, SAXParserFactory and DOM4J 을 사용하여 예방가능.
PHP코드 상에서는 libxml_disable_entity_loader(true); 함수를 이용하여 외부 Entity 사용을 비활성화.
$oldValue = libxml_disable_entity_loader(true);
$dom = new DOMDocument();
$dom->loadXML($xml);
libxml_disable_entity_loader($oldValue);
코드상 DOCTYPE 태그에 대해서 다른 문자열로 치환.
$collapsedXML = preg_replace("/[:space:]/", '', $xml);
if(preg_match("/<!DOCTYPE/i", $collapsedXml)) {
throw new \InvalidArgumentException(
'Invalid XML: Detected use of illegal DOCTYPE’
);
}