Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-32722 — Bloomberg Memray의 이스케이프되지 않은 명령줄 메타데이터를 통한 저장형 XSS | Kitploit
도구/GitHubGitHub/0xmrma/cve-2026-32722
Static Code Analysis (SAST)Vulnerability AnalysisWeb Application ExploitationPenetration TestingPapers & ResearchLearning & Education
GitHub0xmrma/cve-2026-32722

CVE-2026-32722

Bloomberg Memray의 이스케이프되지 않은 명령줄 메타데이터를 통한 저장형 XSS

저장소 보기
14개월 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-32722

블룸버그 Memray의 이스케이프되지 않은 명령줄 메타데이터를 통한 저장형 XSS

소개

저는 Memray(블룸버그의 Python 메모리 프로파일러)를 검토하던 중 다음과 같은 간단한 질문을 염두에 두고 이 문제를 발견했습니다:

공격자가 제어하는 런타임 메타데이터가 안전하지 않은 방식으로 브라우저에 렌더링되는 보고서 출력에 유입될 수 있을까?

이 경우, 답은 '그렇다'였습니다.

이 버그는 Memray의 HTML 보고서 생성 경로에 있었으며, 명령줄 메타데이터가 이스케이프 없이 브라우저에서 열리는 보고서에 렌더링되었습니다. 이로 인해 운영 필드가 실행 가능한 HTML 싱크(sink)로 변했고, 결국 CVE-2026-32722이 되었습니다.

프로젝트: GitHub의 Memray
권고: GHSA-r5pr-887v-m2w9 / CVE-2026-32722

photo0

공격 체인

attacker-controlled argv → metadata.command_line → HTML template sink without escaping → raw markup in generated report → browser-side JavaScript execution


Memray가 하는 일

Memray는 Python 메모리 프로파일러입니다.

Python 프로세스를 계측하고, 할당 동작을 기록하며, 개발자가 다음 사항을 이해하는 데 도움이 되는 보고서를 생성합니다:

  • 메모리가 어디에 할당되는지
  • 어떤 호출 경로가 책임이 있는지
  • 최대 메모리 사용량이 어떤지
  • 메모리가 시간에 따라 어떻게 변하는지

이러한 보고서 중 일부는 HTML로 생성되어 브라우저에서 열립니다.

이는 보고서 생성을 실제 보안 경계로 만듭니다.

핵심 질문은 Memray가 "로컬 도구"인지 여부가 아닙니다.
핵심 질문은 공격자가 제어하는 데이터가 안전하지 않은 방식으로 브라우저 렌더링 출력에 유입될 수 있는지 여부입니다.

이 경우, 그럴 수 있었습니다.


이 버그를 살펴볼 가치가 있었던 이유

많은 사람들이 개발자 도구를 과소평가합니다.

그것은 실수입니다.

도구가 다음을 수행하게 되면:

  • 런타임 메타데이터를 기록하고,
  • 공격자의 영향을 받은 값을 저장하며,
  • 나중에 이를 HTML로 렌더링한다면,

웹 애플리케이션과 동일한 출력 인코딩 위험을 물려받게 됩니다.

이것이 이번 사례의 핵심 문제였습니다.

이 버그는 프로파일링 로직에 있지 않았습니다. 할당 추적에도 있지 않았습니다. 네이티브 메모리 처리에도 있지 않았습니다.

이는 전형적인 신뢰 경계(trust-boundary) 실패였습니다:

  • 신뢰할 수 없는 메타데이터가 시스템에 유입되었고,
  • HTML 싱크로 건너갔으며,
  • 이스케이프 없이 렌더링되었습니다.

그 정도면 실제 취약점을 만들기에 충분합니다.


내가 집중한 경계

저는 무작위 CLI 옵션을 퍼징하거나 크래시를 쫓는 방식으로 Memray에 접근하지 않았습니다.

더 강력한 접근 방식은 가장 높은 확률의 보안 표면을 먼저 식별하는 것이었습니다.

Memray의 경우 그것은 HTML 보고서 생성이었습니다.

왜일까요?

HTML 출력은 브라우저 싱크를 도입하고, 브라우저 싱크는 다음 조건이 충족되면 일반적인 메타데이터 버그를 보안 문제로 바꾸기 때문입니다:

  • 입력이 공격자의 영향을 받고,
  • 출력이 이스케이프되지 않으며,
  • 브라우저가 결과를 텍스트 대신 마크업으로 해석하는 경우입니다.

이것이 바로 이번 사례에서 일어난 일입니다.


근본 원인

이 버그는 두 줄로 요약됩니다.

다음 코드에서:

root@kitploit:~
def get_render_environment() -> jinja2.Environment:
    loader = jinja2.PackageLoader("memray.reporters")
    env = jinja2.Environment(loader=loader)

Jinja 환경이 autoescape 없이 생성됩니다.

그런 다음 다음 코드에서:

root@kitploit:~
Command line: <code>{{ metadata.command_line }}</code><br>

metadata.command_line이 HTML에 직접 렌더링됩니다.

이것이 취약점의 전부입니다.

이것이 악용 가능한 이유

metadata.command_line이 공격자의 영향을 받기 때문입니다.

Memray는 프로파일링되는 프로그램을 실행하는 데 사용된 명령줄을 기록합니다. 즉, argv의 사용자 제어 값이 메타데이터로 보존된 후 나중에 보고서에 삽입됩니다.

따라서 악용 체인은 간단합니다:

  • 공격자가 명령줄 콘텐츠를 제어합니다
  • Memray가 이를 metadata.command_line에 저장합니다
  • 템플릿이 이를 HTML로 내보냅니다
  • 환경이 이를 autoescape하지 않습니다
  • 브라우저가 이를 활성 마크업으로 구문 분석합니다

이로 인해 메타데이터가 실행 가능한 브라우저 콘텐츠로 변합니다.


이것이 단순한 잘못된 렌더링이 아닌 보안 문제인 이유

중요한 차이는 실행(execution)입니다.

많은 버그가 잘못된 형식의 HTML을 생성합니다. 그것만으로는 충분하지 않습니다.

이 경우, 공격자가 제어하는 콘텐츠는 단순히 페이지 소스에 보이는 것에 그치지 않았습니다. 브라우저에 의해 활성 HTML로 해석되어 JavaScript로 실행되었습니다.

이것이 다음 사이의 차이입니다:

  • 형식 손상
  • 그리고 실제 XSS 싱크

따라서 질문은 다음과 같지 않았습니다:

"보고서에 HTML이 나타날 수 있는가?"

실제 질문은 다음과 같았습니다:

"공격자가 제어하는 HTML이 보고서가 열릴 때 실행 가능해질 수 있는가?"

답은 '그렇다'였습니다.


PoC

제 초기 재현 코드는 명시적 스크립트와 공격자가 제어하는 인수를 사용했습니다:

root@kitploit:~
cat > victim.py <<'PY'
x = [b"A" * 1024 for _ in range(1000)]
print("done")
PY

python -m memray run -o poc.bin victim.py ''
python -m memray flamegraph -o poc.html poc.bin

생성된 HTML에는 원시 공격자 제어 마크업이 포함되어 있었습니다:

root@kitploit:~
Command line: <code>~/memray/src/memray/__main__.py run -o poc.bin victim.py </code><br>

생성된 보고서를 열거나 새로고침하면 JavaScript 실행이 트리거되었습니다.

이로써 핵심 주장이 입증되었습니다:

  • 값이 이스케이프되지 않았고,
  • 브라우저가 이를 마크업으로 구문 분석했으며,
  • 싱크가 실행 가능했습니다.

이후, 조정된 공개(coordinated disclosure) 과정에서 유지보수자가 재현 코드를 더 단순화했습니다:

root@kitploit:~
python -m memray run -o poc.bin -c '# '

이 버전은 취약한 경계를 더 직접적으로 격리하기 때문에 더 좋습니다:

  • 추가 파일 없음
  • 추가 애플리케이션 로직 없음
  • 보고서 파이프라인에 유입되는 공격자 제어 명령줄 콘텐츠만 있음

페이로드를 선택한 이유

페이로드는 의도적으로 단순하게 선택되었습니다:

root@kitploit:~

화려한 페이로드에 관한 것이 아닙니다.

다음 이유로 깔끔한 실행 프로브입니다:

  • 외부 인프라가 필요 없습니다
  • 렌더링된 HTML에서 명확하게 보입니다
  • HTML 해석을 즉시 증명합니다
  • 원격 콘텐츠에 의존하지 않고 브라우저 측 실행을 증명합니다

이런 유형의 버그에는 그것으로 충분합니다.


범위 검증

보고서 유형 하나만으로도 이슈를 입증하기에 충분했을 것입니다.

하지만 저는 이것이 단발성인지 구조적인지 알고 싶었습니다.

다음에서 동일한 동작을 확인했습니다:

  • flamegraph 보고서
  • 테이블 보고서
  • --no-web으로 생성된 flamegraph 보고서

이는 두 가지 이유로 중요했습니다.

첫째

취약한 싱크가 여러 HTML 출력에서 재사용된다는 것을 보여주었습니다.

둘째

버그가 외부 CDN 호스팅 자산에 의존하지 않는다는 것을 증명했습니다.

--no-web으로도 여전히 이슈가 재현되었는데, 이는 문제가 원격 JS 동작이 아니라 Memray 자체의 생성 HTML 및 템플릿 처리에 있음을 의미합니다. 이로 인해 사례가 훨씬 강력해졌습니다.


이것이 낮은 심각도로 분류된 이유

유지보수자의 주요 우려는 실질적인 공격자 통제였습니다.

타당한 지적입니다.

인증되지 않은 원격 공격자가 노출된 HTTP 엔드포인트를 공격하여 즉각적인 영향을 얻는 종류의 이슈는 아닙니다.

악용 조건은 더 좁습니다:

  • 공격자가 명령줄 입력에 영향을 줍니다
  • 피해자가 나중에 브라우저에서 생성된 보고서를 엽니다

따라서 현실적인 분류는 낮은 심각도였습니다.

그렇다고 약한 버그라는 뜻은 아닙니다.

심각도는 악용 조건과 예상 영향에 관한 것입니다. 유효성은 이슈가 실제인지 여부에 관한 것입니다.

이 이슈는 분명히 실제였습니다:

  • 공격자 제어 소스
  • HTML 싱크
  • 누락된 이스케이프
  • 실제 JavaScript 실행
  • 결정적 수정

그렇기 때문에 여전히 CVE가 되었습니다.


수정 분석

수정은 최소한이면서도 정확했습니다.

유지보수자는 다음을 변경했습니다:

root@kitploit:~
{{ metadata.command_line }}

다음으로:

root@kitploit:~
{{ metadata.command_line|e }}

취약한 싱크를 직접 해결하기 때문에 올바른 수정입니다.

다음과 같은 원시 마크업을 내보내는 대신:

root@kitploit:~

템플릿은 이제 이스케이프된 텍스트를 내보냅니다:

root@kitploit:~
&lt;img src=x onerror=alert(1)&gt;

이는 브라우저 실행 경로를 제거하면서 명령줄 필드의 정보적 가치를 보존합니다.

유지보수자는 또한 나머지 템플릿 컨텍스트를 검토하고 다음과 같이 결론을 내렸습니다:

  • 여러 필드가 숫자형이었고
  • 일부 문자열은 Memray에 의해 완전히 제어되었으며
  • 스크립트 바인딩 값은 |tojson으로 렌더링되었습니다

따라서 이슈는 metadata.command_line으로 정확히 좁혀졌습니다.

이것이 바로 실제 공개에서 기대하는 수정 검토의 유형입니다.


공개

이 문제는 GitHub Security Advisories를 통해 비공개로 보고되었습니다.

유지보수자들은:

  • 이슈를 검증했고
  • 수정해야 할 자신들의 버그임에 동의했으며
  • 재현 코드를 단순화했고
  • 취약한 싱크를 패치했으며
  • 1.19.2에서 수정을 릴리스했고
  • CVE를 요청했으며
  • 권고를 게시했습니다

이슈에는 다음이 할당되었습니다: CVE-2026-32722


이 버그가 실제로 가르쳐주는 것

여기서 핵심 교훈은 간단합니다:

메타데이터는 운영적으로 보인다고 해서 자동으로 신뢰되지 않습니다.

  • 명령줄은 무해해 보입니다.
  • 보고서 모달은 무해해 보입니다.
  • 로컬 HTML 파일은 무해해 보입니다.

공격자가 제어하는 콘텐츠가 이스케이프 없이 브라우저 렌더링 출력에 유입된다면 그 어떤 것도 중요하지 않습니다.

도구가 HTML을 생성하는 순간, HTML을 생성하는 애플리케이션처럼 취급되어야 합니다.

그것이 진짜 핵심 교훈입니다.


핵심 요점

  • HTML 보고서 생성기는 보안 표면입니다
  • 개발자 도구에도 여전히 출력 인코딩 규율이 필요합니다
  • 로컬 보고서 산출물에는 실제 XSS 싱크가 포함될 수 있습니다
  • 공격자가 제어하는 메타데이터가 싱크에 도달하면 템플릿에서의 이스케이프 누락만으로 충분합니다
  • 낮은 심각도가 낮은 품질을 의미하지는 않습니다
  • 여기서 올바른 사고방식은 맹목적 퍼징이 아닌 신뢰 경계 분석이었습니다

마지막 말

이 취약점은 교묘한 페이로드에 관한 것이 아니었습니다.

올바른 경계를 식별하는 것에 관한 것이었습니다.

Memray는 공격자의 영향을 받은 명령줄 메타데이터를 가져와 이스케이프 없이 생성된 HTML로 렌더링했습니다. 나머지는 브라우저가 해냈습니다.

그렇기 때문에 이것이 CVE-2026-32722이 되었습니다.

Memray 1.19.2에서 수정되었습니다.

photo0
도구 다운로드