# PDF 문서의 잘못된 가림(블랙박스 처리)을 탐지하는 Python 라이브러리 X-ray

> Clean Markdown view of GeekNews topic #25305. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=25305](https://news.hada.io/topic?id=25305)
- GeekNews Markdown: [https://news.hada.io/topic/25305.md](https://news.hada.io/topic/25305.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2025-12-24T16:32:52+09:00
- Updated: 2025-12-24T16:32:52+09:00
- Original source: [github.com/freelawproject](https://github.com/freelawproject/x-ray)
- Points: 3
- Comments: 1

## Topic Body

- **PDF 문서의 부적절한 가림 처리**를 자동으로 찾아내는 Python 라이브러리로, 텍스트가 단순히 검은 사각형으로 덮여 있는 경우를 식별  
- **Free Law Project**가 수백만 개의 PDF를 수집하는 과정에서 발견된 반복적 문제를 해결하기 위해 개발  
- 명령줄 또는 Python 코드에서 실행 가능하며, 결과를 **JSON 또는 Python 객체** 형태로 반환  
- 내부적으로 **PyMuPDF**를 사용해 PDF의 사각형, 텍스트, 색상 정보를 분석하여 가림이 실제로 텍스트를 숨기는지 판단  
- **법률 문서나 공개 자료의 개인정보 노출 방지**를 위한 자동 검증 도구로 활용 가치가 높음  

---

### 개요
- `x-ray`는 PDF 파일 내의 **잘못된 가림(redaction)** 을 탐지하는 Python 라이브러리  
  - 사용자가 PDF 경로를 입력하면, 가림이 제대로 이루어지지 않은 영역을 찾아냄  
  - 결과는 페이지별로 좌표(`bbox`)와 해당 영역의 텍스트(`text`)를 포함한 JSON 형태로 출력  

### 개발 배경
- Free Law Project는 수백만 개의 PDF를 수집하는 과정에서 **가림이 제대로 되지 않은 문서**를 다수 발견  
  - 일부 사용자는 텍스트를 삭제하지 않고 **검은 사각형이나 하이라이트로 덮는 방식**을 사용  
  - 이 경우, 사각형 아래의 텍스트를 선택하면 원문이 그대로 노출됨  
- 이러한 문제의 빈도를 파악하기 위해 `x-ray` 도구를 제작  

### 사용 방법
- **설치**
  - `pip install x-ray` 또는 `uv add x-ray` 명령으로 설치 가능  
- **명령줄 실행**
  - `xray path/to/file.pdf` 형태로 실행하면 JSON 결과 출력  
  - URL 입력 시 원격 PDF 다운로드 후 검사 수행  
  - 여러 URL을 한 번에 검사하려면 `xargs -n 1 xray < urls.txt` 사용  
- **Python 코드 내 사용**
  - `xray.inspect("file.pdf")` 호출 시 Python 객체로 결과 반환  
  - 입력값이 문자열이면 로컬 파일, `https://`로 시작하면 URL, `bytes`면 메모리 내 PDF로 처리  
  - `bytes` 타입으로 파일 경로를 전달하면 작동하지 않음  

### 동작 원리
- 내부적으로 **PyMuPDF**를 이용해 PDF를 분석  
  1. PDF 내의 **사각형(rectangle)** 탐색  
  2. 동일 위치의 **문자(letter)** 탐색  
  3. 사각형을 이미지로 렌더링  
  4. 사각형이 **단일 색상**으로 채워져 있으면 잘못된 가림으로 판단  
- PDF 구조가 복잡해 완벽한 탐지는 어렵지만, 지속적인 개선 진행 중  
- 프로젝트는 **기부 및 후원**을 통해 유지  

### 기여 및 배포
- GitHub의 **issues 목록**을 통해 미지원 사례나 개선 요청 확인 가능  
- 첫 기여 전에는 **기여자 라이선스 동의서(CLA)** 서명 필요  
- 배포는 **GitHub Actions**를 통해 자동화되어 있으며, 수동 배포 시 `poetry publish --build` 명령 사용  

### 라이선스
- **BSD 라이선스**로 공개되어, 다른 프로젝트에 자유롭게 통합 가능  
- Pull Request 및 기능 제안 환영, GitHub 웹 인터페이스에서 직접 수정 가능

## Comments



### Comment 48215

- Author: neo
- Created: 2025-12-24T16:32:52+09:00
- Points: 1

###### [Hacker News 의견들](https://news.ycombinator.com/item?id=46369923) 
- Free Law Project에서 일하면서 수년짜리 복잡한 프로젝트를 많이 하지만, 이번 **X-ray 프로젝트**가 가장 화제가 된 사례임  
  CourtListener의 수백만 문서를 분석하기 위해 X-ray를 만들었고, 사람들에게 이 문제를 알리려는 목적이었음  
  S3 batch job으로 수백만 문서를 몇 분 만에 분석했지만, 결과를 정리하고 보고하는 **진짜 어려운 부분**은 아직 남아 있음
  - [Argelius Labs의 PDF 보안 연구](https://www.argeliuslabs.com/deep-research-on-pdf-redaction-failures-and-security-risks-exploits-and-best-practices/)를 보면, 검은 박스로 가린 부분의 길이만으로도 단어 길이를 추정할 수 있는 **glyph spacing 공격**이 가능하다고 함  
    X-ray가 이런 폰트 메트릭 누출을 이용하는지도 궁금함
  - 폰트의 **kerning**과 픽셀 단위의 재현이 가능하다면 단어를 꽤 정확히 추측할 수 있을 것 같음  
    예를 들어 oioioi와 oooiii는 폰트에 따라 폭이 다름

- 오늘 공개된 파일의 10% 정도만 봤는데, 예를 들어 `EFTA00037069.pdf`에는 `/Prev` 포인터가 있어서 이전 버전이 PDF 내부에 포함되어 있음  
  이건 사소한 수정이지만, 다른 파일에도 있을 가능성이 높음  
  `qpdf --show-object=trailer` 명령으로 직접 확인 가능함  
  이런 **엉망인 편집**이 실수라기보다 의도적일 수도 있다고 생각함
  - 직접 확인해보니, 해당 파일의 수정 내역은 단순히 페이지마다 번호가 추가된 정도였음  
    원본은 이미 완전히 **flattened된 문서**였음
  - 이런 일을 맡은 사람들이 기본적인 지침조차 모른다는 게 놀랍지 않음
  - 실제로는 아무나 불러서 **redaction 작업**을 시키고 있어서, 경험 부족이 문제일 가능성이 큼

- 생각할수록 폰트 **kerning 정보**가 redaction의 큰 취약점이 될 수 있음  
  검은 박스 주변 텍스트의 위치만으로도 가려진 단어의 길이와 형태를 추정할 수 있음  
  렌더링 알고리즘을 알고 있다면 brute-force로 실제 텍스트를 유추할 수도 있을 것 같음  
  혹시 이 문제를 연구한 사람이 있는지 궁금함
  - 자동으로 **kerning을 무작위 조정하는 폰트**가 있으면 좋겠음  
    같은 단어라도 문서마다 간격이 달라지게 하는 방식임
  - 최근에는 LLM의 암호화된 채팅 세션에서 **패킷 크기와 타이밍 분석**으로 정보를 추출한 사례도 있었음  
    일종의 **사이드채널 공격**으로, 이 문제와 유사함
  - redaction의 길이와 예측 가능성에 따라 다름  
    짧고 문맥상 “yes”나 “no” 정도로 한정되면 쉽게 추측 가능하지만, 이름이나 긴 문장은 훨씬 어려움

- PDF는 여전히 **디지털 문서로서 기본적인 결함**이 너무 많음에도 불구하고, 여전히 널리 쓰이는 게 아쉬움

- 단순한 질문인데, 이런 문서 공개에서 **redaction의 목적**이 정확히 무엇인지 궁금함  
  왜 익명성을 유지해야 하는지도 이해가 안 됐음  
  (편집 후) 무고한 사람들도 포함될 수 있다는 점을 생각하니 납득됨
  - 법적으로는 피해자 신원, 진행 중인 수사, 아동 성착취 자료, 국가안보 관련 정보만 가릴 수 있음  
    **평판 손상이나 정치적 이유로 가리는 건 금지**되어 있음  
    하지만 실제 redaction이 이 기준을 지키지 않는다는 우려가 큼
  - WikiLeaks는 개인의 **신체적 위해**로 이어질 수 있는 정보만 가리는 입장이었음  
    예를 들어 GPS 좌표 공개로 폭격 위험이 생길 수 있는 경우임
  - 피해자들은 가해자 보호를 위한 redaction이라면 원치 않는다고 밝힘  
    **책임 추궁**이 더 중요하다고 함
  - 피해자, 목격자, 정보제공자의 신원을 보호하기 위한 목적임
  - 장기 수사 파일에는 **허위 제보나 오보**가 많기 때문에, 무고한 사람의 프라이버시 보호가 필요함  
    하지만 이번 사건은 너무 중요해서 공개가 불가피함

- redacted PDF를 공개할 때는 검은 사각형을 그리고 **이미지로 래스터화**하는 게 기본 절차일 것 같음 🤷
  - 나는 **anti-screenshot** 관련 비즈니스를 운영하는데, 이런 redaction 실패는 정말 흔함  
    단순히 검은 박스를 덮는다고 데이터가 사라지는 게 아님  
    컴플라이언스 현장에서 이런 **오해**를 자주 봄
  - 하지만 어떤 경우에는 문서가 **검색 가능해야 하는 요구사항**이 있어서, 이미지 변환이 불가능할 때도 있음

- Adobe Pro를 제대로 사용하면 PDF의 내용을 **영구적으로 삭제(redact)** 할 수 있음  
  이번 사건은 단순히 PDF 편집기를 제대로 다루지 못한 **아마추어 실수**임  
  수천 명의 변호사와 법무사들이 수십 년간 써온 절차를 무시한 결과임  
  예전에는 종이에 검은 줄을 긋고 인쇄본을 최종본으로 쓰는 방식이었는데, 아마 그 시절 감각으로 작업한 듯함
  - PDF를 종이처럼 생각해서 단순히 **검은 박스**를 덮은 걸로 끝낸 것일 수도 있음  
    텍스트 선택이 막히니 가려졌다고 착각했을 가능성 있음  
    혹은 일부러 이런 식으로 처리해놓고 **실수인 척**하려는 의도였을 수도 있음
  - 미국 연방정부의 변호사나 수사관은 **redaction 교육**을 철저히 받음  
    그래서 이번 일은 단순 실수가 아니라 **의도적인 악의적 준수(malicious compliance)** 로 보는 시각이 많음

- 놀랍게도 브라우저의 PDF 뷰어에서도 redacted 정보가 보임  
  Brave(Linux)에서 [이 문서](https://www.justice.gov/multimedia/Court%20Records/Matter%20of%20the%20Estate%20of%20Jeffrey%20E.%20Epstein,%20Deceased,%20No.%20ST-21-RV-00005%20(V.I.%20Super.%20Ct.%202021)/2022.03.17-1%20Exhibit%201.pdf)를 열고, 90번 단락 첫 줄을 복사해보면 **가려진 텍스트가 그대로 붙여짐**
  - 이런 유형의 **잘못된 redaction**은 X-ray가 탐지할 수 있는 대표적인 사례임

- **ediscovery(전자증거개시)** 개념이 일반 대중에게까지 퍼지는 걸 보니 흥미로움

- 기술 업계 사람들은 비기술 분야 사람들이 얼마나 **기술 문맹**인지 알면 놀랄 것임  
  예전처럼 IT 담당자가 회사의 **전지전능한 신** 취급받던 시절이 떠오름
