flawopen.com/Teardowns/cve-2026-105751-docling-odf-file-disclosure
CVE-2026-105751: Docling ODF 파일 노출
Docling의 ODF 백엔드는 문서의 이미지 참조를 로컬 경로로 처리해 아카이브 밖의 파일을 읽을 수 있었습니다. 2.120.3으로 업그레이드하세요. 수정 버전은 공유 리소스 제어 구성요소를 통해 로드합니다.
CVSS 벡터
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:H/VI:N/VA:N/SC:L/SI:N/SA:N사서가 앨범 안에서 사진을 찾습니다. 사진이 없으면 결함이 있는 리더는 앨범 라벨에 적힌 경로로 서류함을 열고, 로컬 파일을 가져오지 말라는 도서관 규칙은 확인하지 않습니다. 수정 버전은 다른 문서 형식과 같은 보호된 리소스 창구를 사용합니다.
핵심 개념 및 용어
OpenDocument Format (ODF)- .odt 텍스트 문서를 포함하는 오피스 문서 형식 계열입니다. Docling은 문서 XML에서 이미지 참조를 읽습니다.
draw:image- 이미지를 설명하는 ODF XML 요소입니다. xlink:href 값이 리소스를 가리킵니다.
xlink:href- ODF 이미지 요소에 포함된 리소스 참조입니다. 문서 입력값이며 파일 시스템 권한 결정을 대신할 수 없습니다.
ImageResourceLoader- Docling의 공유 이미지 로더입니다. 로컬/원격 가져오기 옵션, 경로 처리, 원격 URL 안전 검사를 적용합니다.
enable_local_fetch- 지원되는 백엔드가 로컬 이미지 리소스를 가져올 수 있는지 제어합니다. 공유 로더를 우회하는 백엔드는 이 제어도 우회합니다.
프레임워크 매핑
- 이 가이드에서 설명하는 약점의 CWE 참조: CWE-22
근본 원인 분석 (Root Cause)
영향받는 Docling 버전의 _image_ref_from_odf_image()는 먼저 ODF 아카이브 안에서 draw:image 리소스를 찾았습니다. 검색 결과가 없으면 fallback이 문서에서 제어하는 xlink:href를 곧바로 Path로 바꾸고 경로가 존재할 때 read_bytes()를 호출했습니다. 이로 인해 공유 ImageResourceLoader가 우회되어 ODF 처리에서는 enable_local_fetch, enable_remote_fetch 및 공통 리소스 해석 규칙이 적용되지 않았습니다. 이미지 유형 필터도 빈 확장자를 허용해 확장자 없는 경로가 통과했습니다. 이미지 디코딩 전에 파일을 읽을 수 있으며, 바이트를 이미지로 디코딩할 수 있을 때 결과 문서의 정보 노출도 확인되었습니다. 공급업체 권고문은 임의 로컬 파일 읽기와 Docling 출력 형식의 이미지 콘텐츠 노출을 설명하며, 후자는 디코딩 가능한 이미지 데이터로 범위를 한정합니다. 이 CVE는 로컬 파일을 읽을 수 있는 프로세스가 제공된 문서를 변환하는 경우에 관한 것입니다. 모든 Docling 배포가 네트워크에서 접근 가능하다는 뜻은 아닙니다. 수정 버전은 외부 참조를 로컬 base path 없이 ImageResourceLoader.load_image_data()로 보내고, ODF 순회에 로더를 전달하며, 허용 이미지 확장자에서 빈 값을 제외합니다. 공유 로더는 기본적으로 로컬 가져오기를 거부하고, 이를 켜면 제한된 base path를 요구합니다. GitHub CNA는 CVSS 4.0 6.9 Moderate(UI:A)로 평가했습니다. 별도의 접근 가능한 서비스와 변환 경로가 확인되지 않았다면 인증 없는 원격 공격으로 설명하지 마세요.
단계별 공격 실행 흐름
문서가 ODF 변환 경로에 들어온다
해당 입력은 Docling 2.107.0~2.120.2가 처리하는 OpenDocument 파일입니다. 문제는 ODF 이미지 백엔드에 있으며 모든 Docling 형식이나 HTML/RAG 통합 전체에 해당하지 않습니다.
이미지 참조는 문서 XML에서 나온다
ODF draw:image 요소가 xlink:href를 제공합니다. Docling은 먼저 아카이브 안에서 리소스를 찾습니다.
아카이브에 없는 항목이 호스트 경로로 대체된다
아카이브 내부 검색이 실패하면 취약한 helper는 같은 참조를 Path로 사용해 직접 읽었습니다. fallback은 공유 로컬 가져오기 설정을 확인하지 않고 경로를 아카이브 안으로 제한하지도 않았습니다.
Docling이 바이트를 이미지 리소스로 처리한다
파일 시스템 읽기는 이미지 디코딩 전에 발생합니다. 지원되는 이미지라면 바이트가 DoclingDocument와 HTML, Markdown 또는 JSON 내보내기에 포함될 수 있습니다.
수정된 로더가 리소스 경계를 복원한다
Docling 2.120.3은 외부 ODF 참조를 ImageResourceLoader로 전달하고 로컬 base path를 지정하지 않으며 확장자 없는 참조를 제외합니다. 신뢰할 수 없는 문서를 변환할 때는 로컬 가져오기를 끄세요.
소스 코드 비교: 취약한 구현 vs 보안 패치
업스트림 코드에서 관련 부분만 발췌한 것이며 단독으로 적용할 패치는 아닙니다. 수정 버전은 백엔드의 enable_local_fetch 및 enable_remote_fetch 옵션으로 ImageResourceLoader를 만들고, ODF 처리에 전달해 외부 참조를 로더로 처리합니다. base_path=None이면 로컬 가져오기를 명시적으로 켜도 제한 디렉터리를 확인할 수 없어 로컬 경로가 거부됩니다. 패치는 빈 이미지 확장자도 거부합니다. 이 발췌만 복사하지 말고 2.120.3 이상으로 업그레이드하세요.
소스 코드 발췌: docling/backend/opendocument_backend.py — 관련 소스 코드 발췌
# 아카이브에서 리소스를 찾지 못하면 문서가 지정한 경로를 읽었다.
if image_data is None and image_url:
image_path = Path(image_url)
if image_path.is_file():
image_data = image_path.read_bytes()
# 수정 경로: 백엔드 옵션으로 구성한 공유 로더를 사용한다.
if image_data is None and image_url and image_loader is not None:
image_data = image_loader.load_image_data(image_url, base_path=None)
엔지니어링 및 시스템 보안 강화 체크리스트
- ✓docling을 2.120.3 이상으로 업그레이드하고 전이적 문서 처리 서비스를 포함해 실제 실행 패키지 버전을 확인하세요.
- ✓신뢰할 수 없는 .odt, .ods 또는 .odp 파일을 받는 파이프라인을 조사하고 변환 프로세스가 읽을 수 있는 OS 파일을 파악하세요.
- ✓신뢰할 수 없는 문서에는 enable_local_fetch를 끄세요. 취약한 버전에서는 공유 로더를 우회하는 ODF 경로를 이 옵션으로 보호할 수 없습니다.
- ✓최소 권한 계정, 최소 읽기 전용 파일 시스템, 파서 프로세스에 비밀정보를 마운트하지 않는 구성을 사용하세요.
- ✓사용자 정의 백엔드에서 문서 경로를 직접 열지 말고 ImageResourceLoader를 사용하세요. 로컬 리소스에는 신뢰할 수 있는 기준 디렉터리를 요구하세요.
- ✓임시 canary 파일을 사용해 아카이브 내부 이미지, 누락 참조, 확장자 없는 참조, 절대 경로, 로컬 가져오기 on/off 회귀 테스트를 추가하세요.
- ✓변환 결과에 예상된 문서 리소스만 있는지 확인하세요. 변환 성공이 다른 파일을 열지 않았다는 증거는 아닙니다.
- ✓영향받는 서비스가 신뢰할 수 없는 ODF 파일을 처리했다면 로그와 출력에서 예상하지 못한 이미지 데이터를 확인하고 서비스 계정이 읽을 수 있는 파일로 조사 범위를 제한하세요.