XML 처리 모듈

XML 처리 모듈

Python의 XML 처리 인터페이스는 xml 패키지에 모여 있어요. ElementTree 같은 가벼운 파서부터 DOM·SAX 바인딩, Expat 파서까지 다양한 방식으로 XML을 다룰 수 있습니다.

출처: Python 표준 라이브러리

본문

Python의 XML 처리용 인터페이스는 xml 패키지로 묶여 있습니다.

주의 — 신뢰할 수 없거나 인증되지 않은 데이터를 파싱해야 한다면 XML 보안(XML security)을 먼저 읽어 주세요.

xml 패키지의 모듈은 SAX 호환이 되는 XML 파서가 적어도 하나 등록되어 있어야 동작해요. Expat 파서는 Python에 포함되어 있으므로 xml.parsers.expat 모듈은 항상 사용할 수 있습니다.

xml.domxml.sax 패키지의 문서는 DOM과 SAX 인터페이스에 대한 Python 바인딩의 정의이기도 합니다.

XML 처리 서브모듈은 다음과 같아요.

  • xml.etree.ElementTree — ElementTree API, 간단하고 가벼운 XML 프로세서
  • xml.dom — DOM API 정의
  • xml.dom.minidom — 최소한의 DOM 구현
  • xml.dom.pulldom — 부분 DOM 트리 구축 지원
  • xml.sax — SAX2 기본 클래스와 편의 함수
  • xml.parsers.expat — Expat 파서 바인딩

XML 보안 (XML security)

공격자가 제어하는 XML을 파싱할 때, 공격자는 XML의 기능을 악용해 서비스 거부(DoS) 공격을 하거나, 로컬 파일에 접근하고, 다른 머신으로 네트워크 연결을 만들거나, 방화벽을 우회할 수 있어요. 이는 Python뿐 아니라 다른 곳에서도 마찬가지입니다.

Python의 내장 XML 파서는 XML 파싱에 libexpat(보통 Expat) 라이브러리를 사용합니다. 기본적으로 Expat 자체는 로컬 파일에 접근하거나 네트워크 연결을 만들지 않아요.

2.7.2보다 낮은 버전의 Expat은 "billion laughs", "quadratic blowup", "large tokens" 취약점이나 메모리를 과도하게 쓰는 문제에 노출될 수 있습니다. Python은 Expat 복사본을 포함하며, 번들된 Expat을 쓰는지 시스템 Expat을 쓰는지는 파이썬 인터프리터를 어떻게 구성했는지에 따라 달라져요. 이런 구버전 Expat을 사용한다면 Python이 취약할 수 있습니다. pyexpat.EXPAT_VERSION으로 버전을 확인해 보세요.

xmlrpc는 "압축 해제 폭탄(decompression bomb)" 공격에 취약합니다.

  • billion laughs / 지수 엔티티 확장 (exponential entity expansion) — Billion Laughs 공격은 여러 단계의 중첩 엔티티를 이용합니다. 각 엔티티가 다른 엔티티를 여러 번 참조하고, 마지막 엔티티 정의는 작은 문자열을 담고 있어요. 지수적 확장 결과 수 기가바이트의 텍스트가 생겨 메모리와 CPU 시간을 많이 소모합니다.
  • quadratic blowup 엔티티 확장 — quadratic blowup 공격은 Billion Laughs 공격과 비슷하게 엔티티 확장을 악용합니다. 중첩 엔티티 대신 수천 자짜리 큰 엔티티 하나를 반복합니다. 지수적 경우만큼 효율적이진 않지만, 깊게 중첩된 엔티티를 금지하는 파서의 대응책을 회피할 수 있어요.
  • 압축 해제 폭탄 (decompression bomb) — 압축 해제 폭탄(일명 ZIP 폭탄)은 gzip HTTP 스트림이나 LZMA 압축 파일 같은 압축 XML 스트림을 파싱할 수 있는 모든 XML 라이브러리에 적용됩니다. 공격자 입장에서는 전송 데이터 양을 세 자릿수 이상 줄일 수 있어요.
  • large tokens — Expat은 끝나지 않은 토큰을 다시 파싱해야 합니다. Expat 2.6.0에서 추가된 보호 조치 없이는 이차(quadratic) 실행 시간으로 이어져 XML을 파싱하는 애플리케이션에 서비스 거부를 일으킬 수 있어요. 이 문제는 CVE 2023-52425로 알려져 있습니다.