
CVE-2026-40179용 최소 Python PoC: 인증되지 않은 Prometheus remote_write를 통해 악성 메트릭 이름을 주입하여 웹 UI에 저장형 XSS를 유발합니다. protobuf 스텁이 필요하지 않습니다.
remote_write를 통한 저장형 XSSCVE-2026-40179 (GHSA-vffh-x6r8-xx99)에 대한 최소한의 의존성만 사용하는 개념 증명(PoC)입니다. 인증 없이 접근 가능한 remote_write 엔드포인트를 통해 Prometheus 웹 UI에 저장형 교차 사이트 스크립팅(XSS)을 주입합니다.
Prometheus 3.x는 메트릭 이름과 레이블 값을 이스케이프 처리 없이 innerHTML을 통해 웹 UI에 렌더링합니다. Prometheus v3에서 레이블 검증을 완화하여 임의의 UTF-8( <, >, " 포함)을 허용했기 때문에, 메트릭 이름에 HTML 페이로드를 담을 수 있으며 이는 누군가 UI를 탐색할 때 실행됩니다.
| 영향 범위 | Prometheus 3.0.0 – 3.5.1 |
| 수정 버전 | 3.5.2 |
| 영향 | 저장형 XSS, 해당 메트릭을 조회하는 모든 사용자의 브라우저에서 실행됨 |
| 취약한 표면 | 그래프 페이지 툴팁, Metrics Explorer |
XSS 자체는 조작된 시리즈를 TSDB에 주입할 경로가 필요합니다. 다음 중 어느 것이든 가능합니다:
remote_write 엔드포인트 (이 PoC가 사용하는 방식),인터넷 또는 LAN에 노출된 Prometheus에 인증이 없으면 위 모든 경로가 그대로 열리며, 이것이 이 취약점을 이론적이 아니라 실질적으로 악용 가능하게 만듭니다.
__name__이 다음과 같은 단일 시계열을 포함하는 POST /api/v1/write 요청 하나를 전송합니다:
pentest_poc_cve_2026_40179
protobuf WriteRequest는 약 40줄로 직접 인코딩되므로 protobuf, prometheus_pb2, 또는 promtool 의존성이 없습니다 — 와이어 압축에는 python-snappy, POST에는 requests만 사용합니다. 따라서 생성된 protobuf 스텁을 빌드할 수 없는 점프 호스트에 쉽게 배포할 수 있습니다.
python3 -m pip install python-snappy requests
python-snappy에는 Snappy C 라이브러리가 필요합니다:
# Debian/Ubuntu
sudo apt install libsnappy-dev
# macOS
brew install snappy
python3 cve-2026-40179-poc.py <target_ip>
이 스크립트는 인증서 검증을 비활성화한 9090 포트의 HTTPS를 가정합니다(자체 서명 인증서를 사용하는 내부 인스턴스의 일반적인 환경). 대상이 일반 HTTP이거나 다른 포트를 사용한다면 main()의 url 줄을 편집하세요.
주입에 성공하면 HTTP 204가 반환됩니다:
POST https://192.0.2.10:9090/api/v1/write -> 204
Prometheus UI 또는 API에서 시리즈를 조회하면 즉시 반환되어야 합니다:
{__name__=~"pentest_poc.*"}
테이블 뷰는 이를 올바르게 이스케이프 처리하여 페이로드를 일반 텍스트로 표시합니다. 이는 정상적인 동작이며 취약한 표면이 아닙니다.
Metrics Explorer(쿼리 상자 옆의 메트릭 브라우저)를 열고 pentest_poc를 검색한 다음, 표시된 항목에 마우스를 올리세요.
3.2.1 실전 테스트에서 Metrics Explorer 경로는 확실하게 실행되었지만 그래프 탭 툴팁은 재현되지 않았습니다 — 주입된 샘플(값 1.0)이 플롯된 차트에 시각적으로 렌더링되지 않았고, 범례에 마우스를 올려도 트리거되지 않았습니다. 두 표면 모두 권고에 명시되어 있습니다. 대상 버전에서 하나가 실행되지 않으면, 취약하지 않다고 결론 내리기 전에 다른 하나를 시도해 보세요.
기본 페이로드는 console.log()를 사용하므로 이를 찾고 있지 않은 사람에게 방해가 되지 않습니다. 눈에 보이는 데모(예: 보고서용 스크린샷)가 필요하다면 METRIC_NAME을 alert()를 사용하도록 변경하세요:
METRIC_NAME = ('pentest_poc_cve_2026_40179'
'')
주입된 시리즈는 영구적입니다. 한 번 쓰이면 보존 기간이 만료될 때까지 TSDB에 남아 있습니다. 이를 제거하려면 관리자 API가 필요한데, 기본적으로 비활성화되어 있습니다:
# Prometheus가 --web.enable-admin-api로 시작된 경우에만 작동
curl -X POST -g 'https://<target>:9090/api/v1/admin/tsdb/delete_series?match[]={__name__=~"pentest_poc.*"}'
curl -X POST 'https://<target>:9090/api/v1/admin/tsdb/clean_tombstones'
관리자 API가 꺼져 있으면 원격 정리 경로가 없습니다. 유일한 대안은 호스트에서 로컬로 실행하는 promtool tsdb뿐이며, 여기에 접근 권한이 없을 가능성이 높습니다.
실질적인 영향:
job="pentest_poc"). 따라서 쉽게 찾을 수 있고 분명히 테스트 아티팩트임을 알 수 있습니다.실제 시스템 대신 일회용 인스턴스로 재현하려면:
docker run --rm -p 9090:9090 prom/prometheus:v3.2.1 \
--config.file=/etc/prometheus/prometheus.yml \
--web.enable-remote-write-receiver \
--web.enable-admin-api
그런 다음 스크립트를 127.0.0.1로 지정하세요(main()에서 URL 스킴을 http://로 변경). --web.enable-admin-api로 시작하면 이후 실제로 시리즈를 삭제할 수 있습니다.
basic_auth_users가 포함된 --web.config.file.--web.enable-remote-write-receiver를 활성화하지 말고, 인증 없이 노출하지 마세요.(1)만으로도 XSS는 수정되지만, 인증되지 않은 Prometheus는 그 자체로 상당한 정보 노출 표면입니다. 전체 메트릭 이름 목록, 스크레이프 대상 목록, 내부 호스트 이름이 모두 자격 증명 없이 읽힐 수 있습니다.
이 도구는 승인 아래 작업하는 방어자, 연구자, 테스터를 위해 공개되었습니다. 이 취약점은 공개적으로 공개되었으며 업스트림에서 패치되었습니다.
이것을 시스템에 실행하면 시스템에 영구 데이터가 기록됩니다. 소유하지 않았거나 명시적인 서면 승인을 받지 않은 인프라에 사용하지 마세요.
MIT — LICENSE 참조.