문서·데이터 라이브러리Document & data libraries

zip-bomb-budget-check

신뢰할 수 없는 ZIP(docx·xlsx·pptx 포함)을 풀지 않고 크기와 개수 예산으로 검사합니다. 압축 폭탄, 경로 탈출, 중복, CRC를 봅니다.

GitHub에서 보기View on GitHub

어떤 문제를 푸나The problem

오피스 문서는 ZIP이고 ZIP이 선언하는 크기는 거짓일 수 있습니다. Python의 zipfile은 선언한 크기에서 읽기를 멈추므로 10바이트라고 적힌 헤더가 수 기가바이트로 풀리는 스트림을 숨길 수 있습니다.

이 도구는 모든 멤버를 직접 inflate하며 누적 바이트 예산을 적용합니다(한 번에 최대 64KB 출력). 지역 헤더와 중앙 디렉터리가 서로 다르면 거부합니다.

이런 분께 맞습니다Who it is for

사용자가 올린 문서를 파싱하는 서버를 만드는 개발자.

무엇을 하나What it does

  • 거부 사유는 고정된 문장입니다. 압축 크기·항목 수 초과, 안전하지 않은 경로(.., 절대 경로, 역슬래시, Windows 예약 이름), 중복(대소문자·유니코드·끝점 무시), 암호화, 심볼릭 링크, 실제 크기 초과, 선언과 다른 크기나 CRC, 손상된 deflate, 지원하지 않는 압축입니다.
  • stored와 deflate만 받습니다.
  • 종료 코드 0은 예산 안, 1은 거부, 3은 파일을 읽지 못함(통과가 아님)입니다.

직접 돌려 본 출력Real output

저장소의 examples 폴더를 실행한 결과입니다.

$ bash examples/demo.sh
# Default budget: 40 MiB expanded, 5000 entries. Nothing is ever extracted.
$ python3 scripts/check_zip.py .demo-tmp/ok.zip
{"entries": 2, "bytes": 24, "status": "within-budget"}
[exit 0]

$ python3 scripts/check_zip.py .demo-tmp/bomb.zip
{"status": "rejected", "reason": "declared size budget exceeded"}
[exit 1]

$ python3 scripts/check_zip.py .demo-tmp/traversal.zip
{"status": "rejected", "reason": "unsafe member path"}
[exit 1]

$ python3 scripts/check_zip.py .demo-tmp/dupes.zip
{"status": "rejected", "reason": "duplicate member"}
[exit 1]

알아둘 한계Limits

  • 풀지 않으며 매크로를 검사하거나 문서가 안전하다고 증명하지 않습니다. 중첩 아카이브는 재귀 검사하지 않습니다.
  • 검사와 파싱 사이에 파일이 바뀌지 않게 하십시오.

받아서 쓰기Get it

# 저장소를 받습니다
git clone https://github.com/Kein-chronicle/zip-bomb-budget-check.git

# Claude Code 스킬로 쓰려면 이 폴더 이름으로 받습니다
git clone https://github.com/Kein-chronicle/zip-bomb-budget-check.git ~/.claude/skills/zip-budget-check

정보Info

분류Category
문서·데이터 라이브러리Document & data libraries
형태Type
명령줄 도구Command-line tool
라이선스License
MIT
필요한 것Requires
Python 3.10 이상
저장소Repository
zip-bomb-budget-check
토픽Topics
security zip zip-bomb path-traversal docx python file-upload zero-dependencies

2026-10-18 기준: 저장소의 테스트를 로컬에서 실행해 통과했고, 예제 출력은 저장소의 examples 폴더를 실제로 실행한 결과입니다.

공유하기Share

문자Message 네이버 블로그Naver Blog X Facebook