X, Vercel, Cursor, Discord 등 수백 개 기업을 공급망 공격으로 침투한 방법
(gist.github.com/hackermondev)- 16살 고등학생이 Mintlify 플랫폼의 취약점을 이용해 X, Vercel, Cursor, Discord 등 주요 기업의 문서 사이트에서 교차 사이트 스크립팅(XSS) 공격이 가능했던 사례를 정리해 공개함. 이 취약점을 통해 버그바운티로 11,000 달러 수령
- Mintlify의 내부 경로
/_mintlify/static/[subdomain]/[...route]가 도메인 검증 없이 외부 파일을 불러올 수 있는 구조로 되어 있었음 - 공격자는 SVG 파일에 자바스크립트를 삽입해 Discord 등 주요 서비스 도메인에서 악성 스크립트를 실행할 수 있었음
- 취약점은 Mintlify를 사용하는 거의 모든 고객사에 영향을 미쳤으며, 단 한 번의 링크 클릭으로 계정 탈취가 가능했음
- 이 사건은 공급망 보안의 단일 취약점이 대규모 피해로 이어질 수 있음을 보여주는 사례로 평가됨
Discord에서의 발견
- 2025년 11월 Discord가 AI 기반 문서 플랫폼 Mintlify로 전환하면서 취약점 탐색이 시작됨
- 기존 커스텀 플랫폼에서 Mintlify로 이전한 직후, 연구자는 새 문서 시스템의 구조를 분석
- Discord의 문서 도메인(
discord.mintlify.app)이 Mintlify의 내부 경로(/_mintlify/*)를 그대로 노출하고 있었음- 이 경로는 인증 등 주요 기능을 위해 필수적으로 접근 가능해야 했음
Mintlify 플랫폼 구조
- Mintlify는 Markdown 기반 문서 작성을 지원하며, 이를 자동으로 웹 문서로 변환하는 서비스
- 모든 문서 사이트는
*.mintlify.app하위 도메인 또는 커스텀 도메인에서 운영 - 내부적으로
/_mintlify/api/user,/_mintlify/markdown/,/_mintlify/static/등의 엔드포인트를 사용
취약점 탐색 과정
-
/_mintlify/_markdown/_sites/[subdomain]/[...route]엔드포인트가 도메인 검증 없이 다른 문서의 파일을 반환함을 발견- 단, 이 경로는 렌더링되지 않은 Markdown 텍스트만 반환해 코드 실행은 불가능했음
- 이후 Mintlify CLI 패키지를 분석해
/_mintlify/static/[subdomain]/[...route]엔드포인트를 추가로 발견- 이 경로는 정적 파일을 반환하며, 파일 확장자 화이트리스트를 적용
- HTML·JS 파일은 차단되었으나 SVG 파일은 허용되어 있었음
공격 실현
- 공격자는 자바스크립트가 삽입된 SVG 파일을 자신의 Mintlify 문서에 업로드
- Discord 도메인에서 해당 파일을 호출(
https://discord.com/_mintlify/_static/.../lmao.svg)하면 스크립트가 실행됨 - 이를 통해 Discord뿐 아니라 Mintlify를 사용하는 모든 기업의 문서 도메인에서 XSS 실행 가능
협업 및 보고
- 연구자는 다른 보안 연구자들과 협력해 취약점을 검증
- Discord는 보고 직후 개발자 문서 전체를 2시간 동안 비활성화하고, 이후 기존 플랫폼으로 복귀
- 관련 조치 내용은 Discord Status 페이지에 기록
- Mintlify는 Discord를 통해 취약점을 인지한 후, 엔지니어링 팀과 연구자 간 Slack 채널을 개설해 즉시 수정 작업 진행
영향 범위
- X(Twitter), Vercel, Cursor, Discord 등 Mintlify 고객사 대부분이 영향권
- 각 기업의 공식 도메인에서 단일 악성 링크로 계정 탈취 가능성 존재
- 공급망 단일 취약점이 수백 개 기업의 보안에 연쇄적 위험을 초래할 수 있음
보상 및 결론
- 연구팀은 총 약 11,000달러의 버그 바운티를 수령
- Discord가 4,000달러, Mintlify가 개별 취약점에 대해 추가 보상 지급
- 이 사례는 공급망 보안의 중요성과 단일 플랫폼 취약점의 파급력을 보여주는 대표적 사례로 남음
Hacker News 의견들
-
이 익스플로잇은 정말 무서운 사례임
단 한 개의 링크만 클릭해도, 예를 들어 https://discord.com/_mintlify/static/evil/exploit.svg 같은 링크를 누르면, Discord 도메인에서 자바스크립트가 실행됨
그 결과 세션 쿠키나 토큰이 탈취되어 계정이 완전히 장악될 수 있고, 개발자 앱이나 웹훅을 조작하거나, API를 통해 서버를 삭제하거나 결제 정보를 이용해 Nitro를 구매하는 등 피해가 큼
이런 피해 규모를 생각하면 $4,000의 버그 바운티는 너무 적은 보상처럼 느껴짐- 쿠키나 토큰을 훔치려면 HTTP-only가 아닌 쿠키나 localStorage에 토큰이 있어야 하는데, Discord가 그런 구조인지 확실한가 궁금함
세션 쿠키를 항상 HTTP-only로 설정하면 이런 공격에 훨씬 강해짐
프론트엔드 개발자 중 이런 기본 보안 개념을 모르는 사람이 많다는 게 놀라움 - “$4,000은 너무 적다”는 말에 공감함
블랙마켓에서는 훨씬 더 높은 가치를 가질 수 있었을 것임
- 쿠키나 토큰을 훔치려면 HTTP-only가 아닌 쿠키나 localStorage에 토큰이 있어야 하는데, Discord가 그런 구조인지 확실한가 궁금함
-
SVG 파일에 스크립트를 넣을 수 있다는 사실 자체가 보안상 실수였다고 생각함
인터랙티브한 데모나 게임을 SVG 하나로 구현할 수 있는 건 멋지지만, 그만큼 취약점의 온상이 됨
그래서 많은 플랫폼이 SVG 업로드를 금지하거나 미리보기를 차단함
Discord에서도 SVG를 올리면 코드 그대로 보이고, Facebook Messenger나 WeChat 등에서도 공유가 불가능함
파일 크기가 작고 해상도 독립적인 장점이 있음에도, 여전히 래스터 이미지 포맷이 더 널리 쓰이는 현실이 아쉬움- 모든 SVG는 업로드 시와 렌더링 시 철저히 정화(sanitize) 되어야 함
Rails의 Active Storage는 기본적으로 SVG를 정화하지 않으니 주의해야 함 - XML 외부 엔티티(XXE) 문제도 비슷한 사례였음
관련 내용은 OWASP 문서 참고 - 메신저 앱이
<script>태그를 단순히 무시하도록 하면 해결될까 궁금함
하지만 그 정도로는 충분하지 않을 수도 있음 - Flash 시절의 보안 버그들을 다시 떠올리게 하는 상황임
- SVG의 더 큰 문제는 렌더링 결과가 소프트웨어마다 다르다는 점임
래스터 포맷에서는 이런 문제가 거의 없음
- 모든 SVG는 업로드 시와 렌더링 시 철저히 정화(sanitize) 되어야 함
-
이번 사건은 요즘 AI 스타트업 생태계의 단면을 보여주는 것 같음
VC 자금으로 성장한 AI 문서화 스타트업이 보안 검증도 없이 대형 고객을 확보하고, 결국 수백만 명이 위험에 노출됨
Mintlify가 얼마 전 복잡한 캐싱 아키텍처를 자랑하는 블로그를 썼지만, 실제로는 기본 보안조차 모르는 듯함
이런 상황에서 취약점을 발견한 사람은 고작 $5,000을 받음
요즘 AI 기반 개발 문화가 얼마나 취약한지를 보여주는 사례라고 생각함- 사실 이런 공격에 취약한 건 AI 스타트업뿐 아니라 자바스크립트 생태계 전체의 구조적 문제임
복잡한 의존성 체인과 다중 서드파티 DLL 지옥이 근본 원인임 - 대부분의 XSS는 단일 도메인 구조 때문임
Discord가 API 문서를 discord.com에서 직접 서비스하지 않았다면 이런 문제는 없었을 것임 - 문서 사이트에 복잡한 캐싱 구조가 왜 필요한지 의문임
CDN만으로 충분하지 않은가 싶음
- 사실 이런 공격에 취약한 건 AI 스타트업뿐 아니라 자바스크립트 생태계 전체의 구조적 문제임
-
고객 계정을 완전히 장악할 수 있는 버그인데 보상 금액이 너무 적음
요즘 시대에 XSS를 허용할 이유도 없음 -
이런 취약점을 찾은 16세 해커를 정규직 혹은 파트타임으로 고용해 상시 보안 점검을 시키면 어떨까 생각함
연 $50,000만 줘도 회사 보안이 획기적으로 강화될 것 같음- 하지만 연구자에게 성과 압박을 주는 계약 구조는 부적절함
버그 바운티는 결과에 따라 보상하므로 더 효율적임
다만 보상이 낮으면 연구자가 제3자에게 팔 유혹이 생김 - 대부분의 버그 바운티 참가자는 전문 영역이 다름
XSS, IAM, 쉘 익스플로잇 등 각자 특화된 분야가 있어서 한 명이 모든 걸 커버하기 어려움 - 솔직히 이런 회사들은 보안에 큰 관심이 없음
- 하지만 연구자에게 성과 압박을 주는 계약 구조는 부적절함
-
16살이 이런 걸 발견했다니 대단함
하지만 XSS를 공급망 공격(supply chain attack) 으로 부르는 건 생소함- 용어 사용이 다소 잘못된 것 같지만, 나이가 어리니 이해됨
- 그래도 공급망 관점에서 보면 일리가 있음
Mintlify 같은 중간 단계에서 문제가 생기면, 최종 사용자는 아무런 방어 수단이 없음
신뢰된 체인 안에서 악성 코드가 전달되는 셈이라, 일종의 공급망 수준의 XSS로 볼 수도 있음
-
협력자의 보고서에는 더 심각한 RCE 취약점도 포함되어 있음
자세한 내용은 이 블로그 참고 -
이런 사례를 보면,
1️⃣ Content Security Policy(CSP) 를 반드시 설정해야 함
2️⃣ NodeJS 서버에서는--disallow-code-generation-from-strings옵션을 기본으로 써야 함
Vercel 같은 서비스 제공자는 CSP 미사용 시 경고를 띄워야 함
추가로 참고할 만한 NodeJS 보안 플래그는 이 글에 정리되어 있음 -
사용자 인증이 걸린 메인 도메인에서 서드파티 서비스로 프록시하는 건 최악의 선택임
Mintlify를 dev-docs.discord.com 같은 별도 서브도메인으로 분리했어야 함- 나도 Mintlify와 비슷한 제품을 운영하지만, 코드베이스 접근이나 Git 연동은 지원하지 않음
고객이 원하더라도 보안상 위험이 너무 큼
다만 SEO 때문에 메인 도메인에 문서를 두려는 수요가 많음
Mintlify 입장에서도 이번 일은 큰 스트레스일 것 같음 - 이런 취약점의 핵심은 도메인 분리 실패임
서드파티용 서브도메인을 쓰고, 메인 앱의 인증 쿠키는 host-only로 제한해야 함
가능하면 완전히 다른 도메인(예: discorddocs.com)을 쓰는 게 더 안전함 - 기업들이 문서 사이트를 메인 도메인에 두는 이유는 코드 예제에 실제 API 키를 자동 삽입하기 위함임
하지만 보안 리스크에 비하면 너무 위험한 선택임
- 나도 Mintlify와 비슷한 제품을 운영하지만, 코드베이스 접근이나 Git 연동은 지원하지 않음
-
이제 SVG 파일은 절대 열지 않겠음
16살이 이런 걸 찾아냈다는 게 정말 전설적임- 그래도 열어야 한다면 샌드박스된 브라우저 환경에서만 열어야 함