보안이슈

justhtml 취약점 5건 분석|정화 경계와 대응

justhtml의 HTML 정화·Markdown 변환·URL 직렬화·selectedcontent 경로에 걸친 CVE 5건을 영향 조건과 수정 버전별로 다룹니다.

justhtml 취약점 5건의 정화 경계와 대응을 표현한 한국어 표지
justhtml 취약점 5건의 정화 경계와 대응을 표현한 한국어 표지

한 제품 안에서 갈라지는 다섯 취약 경로

justhtml은 HTML을 파싱하고 정화하거나 Markdown으로 바꾸는 Python 라이브러리입니다. 이번 인계에는 CVE-2026-7808, CVE-2026-8445, CVE-2026-5388, CVE-2026-77088, CVE-2026-74793이 하나의 제품군으로 묶였습니다. 공통점은 단순히 ‘악성 태그 하나를 놓쳤다’는 데 있지 않습니다. 입력을 DOM으로 바꾸는 과정, 정화 정책을 재사용하는 과정, URL을 다시 직렬화하는 과정, HTML을 Markdown으로 바꾼 뒤 다시 렌더링하는 과정처럼 서로 다른 신뢰 경계에서 안전 판단과 최종 해석이 어긋날 수 있다는 점이 핵심입니다.

운영자는 justhtml 패키지의 존재만 확인해서는 충분하지 않습니다. 애플리케이션이 기본 HTML 정화만 사용하는지, 프로그램에서 DOM 노드를 직접 만들거나 수정하는지, 사용자 입력을 Markdown으로 변환한 뒤 다른 렌더러에 넘기는지, SVG·MathML을 보존하는 사용자 정책을 적용하는지까지 사용 경로를 나눠 봐야 합니다. 같은 버전이라도 실제 노출 면은 코드 경로에 따라 달라집니다.

영향 조건의 분리

  • 기본 JustHTML 정화 경로와 프로그램에서 만든 DOM을 정화하는 경로를 구분합니다.
  • to_markdown() 결과를 브라우저용 HTML로 다시 렌더링하는지 확인합니다.
  • 정화 정책 객체와 중첩 상태를 여러 요청에서 재사용하거나 수정하는지 확인합니다.
  • SVG·MathML, style, base, meta refresh 같은 요소를 사용자 정책으로 보존하는지 확인합니다.
  • URL 정화 도우미 또는 직렬화 결과를 보안 허용목록 판단에 사용하는지 확인합니다.

CVE-2026-7808과 정책·DOM 경계

공식 권고는 1.16.0에서 정화, 직렬화, 프로그램 방식 DOM 처리와 관련된 여러 문제를 수정했다고 설명합니다. 1.15.0 이하에서는 중첩된 정화 정책 상태가 바뀐 뒤 이전에 컴파일된 정화기가 남거나, 내보낸 기본 정책의 내부 상태가 프로세스 전체에서 변형될 수 있었습니다. 프로그램에서 만든 DOM의 대소문자 혼합 태그, 사용자 지정 drop_content_tags, 신뢰할 수 없은 doctype과 노드 이름 직렬화도 점검 대상입니다.

SVG·MathML을 보존하는 정책은 별도의 위험 면을 만듭니다. 정화가 끝난 뒤 속성을 바꾸는 애니메이션 요소, 외부 URL을 참조하는 표현 속성, 네임스페이스와 실제 직렬화 결과가 다른 노드가 남을 수 있기 때문입니다. 기본 설정에서 일반 HTML만 처리하는 애플리케이션과 사용자 정책으로 외부 네임스페이스를 살리는 애플리케이션을 같은 방식으로 평가하면 안 됩니다. 업데이트 전까지는 내보낸 기본 정책이나 중첩 상태를 수정하지 않고, 신뢰할 수 없은 입력에서 SVG·MathML과 style·script 보존을 피하는 것이 공급사 권고와 맞습니다.

CVE-2026-8445와 Markdown 변환

CVE-2026-8445는 to_markdown()이 HTML처럼 보이는 텍스트를 충분히 이스케이프하지 못하는 경로와 연결됩니다. 입력 단계에서는 텍스트였던 꺾쇠괄호 내용이 Markdown 출력에 그대로 남고, 그 결과를 원시 HTML을 허용하는 Markdown 렌더러가 다시 해석하면 활성 HTML이 될 수 있습니다. title, textarea, noscript, plaintext 같은 파싱 상태나 엔터티에서 복원된 텍스트가 이 경계에 들어갑니다. 실제 위험 판단에는 ‘정화했다’는 사실보다 Markdown 결과가 어디에서 어떤 옵션으로 렌더링되는지가 더 중요합니다. 1.11.0 이하를 사용하는 변환 경로는 1.12.0 이상으로 올려야 합니다.

CVE-2026-5388과 URL·직렬화

CVE-2026-5388 묶음은 1.14.0 이하의 URL 정화 도우미, HTML 직렬화, Markdown passthrough, 사용자 정책 가장자리 조건을 다룹니다. 엔터티로 표현된 스킴이 속성 파싱 뒤 활성 URL이 되거나, 역슬래시가 포함된 상대 URL이 브라우저에서 원격 주소로 해석될 수 있었습니다. 호스트 허용목록이 있은 상태에서 잘못된 대괄호 호스트가 예외를 일으키는 문제와, 프로그램에서 만든 태그·속성·주석이 직렬화 과정에서 활성 마크업으로 바뀌는 문제도 포함됩니다.

사용자 정책이 ping, attributionsrc, imagesrcset, meta refresh, base href, style을 보존한다면 URL이 하나라는 가정이나 상대 경로라는 가정이 깨질 수 있습니다. 이 경로는 1.15.0 이상으로 업데이트하는 것이 기본 조치입니다. 즉시 올리기 어렵다면 html_passthrough를 신뢰할 수 없은 콘텐츠에 사용하지 않고, URL을 담은 속성과 리디렉션·기준 URL·스타일 자원 로딩을 허용하는 정책을 줄여야 합니다.

CVE-2026-77088과 코드 구간 이탈

CVE-2026-77088은 0.9.0부터 1.21.0까지의 to_markdown() 코드 구간 처리에 영향을 줍니다. code 요소의 텍스트와 링크 안의 pre 텍스트를 인라인 코드 구간으로 만들 때 백틱 길이만 조절했지만, 빈 줄은 Markdown 블록 경계를 끝냅니다. 이 때문에 정화된 텍스트가 코드 구간 밖으로 밀려나고, 이후 렌더러에서 원시 HTML이나 Markdown으로 다시 처리될 수 있습니다. 공급사는 1.22.0을 수정 버전으로 제시합니다. Markdown을 저장·전송·미리보기하는 서비스는 변환 단계와 렌더링 단계를 함께 회귀 시험해야 합니다.

CVE-2026-74793과 기본 정화 경로

CVE-2026-74793은 selectedcontent 투영 과정에서 정화 대상 하위 트리가 복제된 뒤 제거 목록에 등록되지 않은 문제를 중심으로 합니다. 공식 권고는 3.10.1 이하에서 기본 JustHTML(html).to_html() 경로가 공격자가 제어한 SVG·MathML 하위 트리의 활성 속성을 출력할 수 있다고 설명합니다. 사용자 정의 정책이 아니라 문서화된 기본 정화 경로에 닿는다는 점에서 우선순위가 높습니다. 같은 투영 함수에는 작은 입력이 큰 CPU·메모리 비용을 만들 수 있은 가용성 문제도 함께 기술돼 있습니다. 수정 경계는 3.11.0 이상입니다.

justhtml의 영향 경로와 업데이트 점검 순서를 정리한 한국어 인포그래픽
영향 경로 식별부터 최신 버전 적용까지의 점검 순서

운영자 점검 순서

  1. SBOM, 잠금 파일, 컨테이너 이미지에서 justhtml 버전과 실제 배포 산출물을 확인합니다.
  2. HTML 정화, 프로그램 DOM, URL 도우미, to_markdown, Markdown 재렌더링 호출 지점을 코드 검색으로 분리합니다.
  3. 사용자 입력이 통과하는 정책 객체의 생성·복사·재사용 방식을 확인하고 기본 정책 내부를 수정하는 코드를 제거합니다.
  4. 단일 최신 버전으로 단순 비교하지 말고 각 서비스가 사용하는 기능 경로에 필요한 수정 경계를 대조합니다.
  5. 업데이트 뒤 HTML 출력과 Markdown 재렌더링 결과를 보안 회귀 시험에 넣고, SVG·MathML·URL·코드 구간 샘플을 포함합니다.
  6. 패키지 잠금 파일과 배포 이미지가 새 버전을 실제로 포함하는지 다시 확인합니다.

버전 경계 해석과 배포 전략

다섯 CVE의 수정 버전은 하나로 모이지 않습니다. CVE-2026-8445는 1.12.0, CVE-2026-5388은 1.15.0, CVE-2026-7808은 1.16.0, CVE-2026-77088은 1.22.0, CVE-2026-74793은 3.11.0을 각각 경계로 합니다. 따라서 오래된 유지보수 분기를 부분적으로 올리는 방식보다 애플리케이션 호환성을 검토한 뒤 지원되는 최신 계열로 수렴하는 편이 누락 위험을 줄입니다. 서비스별로 직접 의존성과 전이 의존성을 구분하고, 빌드 단계에서 결정된 버전이 실행 환경까지 유지되는지 확인해야 합니다.

업데이트 검증은 페이지가 정상 표시되는지만 보는 기능 시험으로 끝내지 않습니다. 정화된 출력이 다시 다른 파서나 Markdown 렌더러로 넘어가는지, 캐시된 정책 객체가 요청 사이에서 공유되는지, 사용자 정책의 허용 요소가 브라우저에서 네트워크 요청이나 스크립트 동작으로 이어지는지까지 확인해야 합니다. 보안 경계가 두 번 이상 이어지는 파이프라인에서는 각 단계가 ‘안전한 문자열’을 같은 의미로 해석한다는 보장이 없습니다.

정보 확인 기준

2026년 8월 24일 14:00 KST 회차 기준으로 justhtml 공식 GitHub 보안 권고와 CVE 레코드를 대조했습니다. 조치 기준은 각 권고가 제시한 영향 경로와 수정 버전을 따릅니다.

확인한 출처

  1. Multiple security fixes in justhtml 1.15.0 found by LLMjusthtml GitHub Security Advisory · 공식 자료
  2. justhtml: to_markdown() code-span blank-line breakout enables XSSjusthtml GitHub Security Advisory · 공식 자료
  3. Default sanitizer bypass: selectedcontent projection re-inserts unsanitized subtreejusthtml GitHub Security Advisory · 공식 자료

사실관계와 수치는 연결된 자료에서 다시 확인할 수 있습니다.

독자 의견

의견을 남겨주세요

0

아직 등록된 댓글이 없습니다.

개인정보·광고·외부 연락처는 입력하지 마세요.