- Một học sinh trung học 16 tuổi đã công khai tổng hợp một trường hợp có thể thực hiện tấn công cross-site scripting (XSS) trên các trang tài liệu của những công ty lớn như X, Vercel, Cursor, Discord bằng cách khai thác lỗ hổng của nền tảng Mintlify. Thông qua lỗ hổng này, người này đã nhận được 11.000 USD tiền thưởng bug bounty
- Đường dẫn nội bộ của Mintlify
/_mintlify/static/[subdomain]/[...route] được thiết kế theo cách có thể tải tệp bên ngoài mà không xác thực tên miền
- Kẻ tấn công có thể chèn JavaScript vào tệp SVG để thực thi script độc hại trên tên miền của các dịch vụ lớn như Discord
- Lỗ hổng này ảnh hưởng đến gần như mọi khách hàng sử dụng Mintlify, và chỉ với một lần nhấp vào liên kết là có thể chiếm đoạt tài khoản
- Vụ việc này được đánh giá là một ví dụ cho thấy chỉ một lỗ hổng trong bảo mật chuỗi cung ứng cũng có thể dẫn đến thiệt hại trên diện rộng
Phát hiện trên Discord
- Vào tháng 11 năm 2025, khi Discord chuyển sang nền tảng tài liệu AI Mintlify, quá trình tìm kiếm lỗ hổng bắt đầu
- Ngay sau khi chuyển từ nền tảng tùy chỉnh cũ sang Mintlify, nhà nghiên cứu đã phân tích cấu trúc của hệ thống tài liệu mới
- Tên miền tài liệu của Discord (
discord.mintlify.app) đã lộ nguyên trạng đường dẫn nội bộ của Mintlify (/_mintlify/*)
- Đường dẫn này bắt buộc phải có thể truy cập để phục vụ các chức năng quan trọng như xác thực
Cấu trúc nền tảng Mintlify
- Mintlify là dịch vụ hỗ trợ soạn thảo tài liệu dựa trên Markdown và tự động chuyển chúng thành tài liệu web
- Mọi trang tài liệu đều vận hành trên tên miền phụ
*.mintlify.app hoặc tên miền tùy chỉnh
- Bên trong, hệ thống sử dụng các endpoint như
/_mintlify/api/user, /_mintlify/markdown/, /_mintlify/static/
Quá trình tìm kiếm lỗ hổng
- Đã phát hiện endpoint
/_mintlify/_markdown/_sites/[subdomain]/[...route] trả về tệp của tài liệu khác mà không xác thực tên miền
- Tuy nhiên, đường dẫn này chỉ trả về văn bản Markdown chưa render, nên không thể thực thi mã
- Sau đó, khi phân tích gói Mintlify CLI, nhà nghiên cứu tiếp tục phát hiện endpoint
/_mintlify/static/[subdomain]/[...route]
- Đường dẫn này trả về tệp tĩnh và áp dụng whitelist phần mở rộng tệp
- Tệp HTML và JS bị chặn, nhưng tệp SVG lại được cho phép
Khai thác tấn công
- Kẻ tấn công tải lên tài liệu Mintlify của mình một tệp SVG có nhúng JavaScript
- Khi gọi tệp đó từ tên miền Discord (
https://discord.com/_mintlify/_static/.../lmao.svg), script sẽ được thực thi
- Nhờ vậy, không chỉ Discord mà mọi tên miền tài liệu của các công ty dùng Mintlify đều có thể bị thực thi XSS
Phối hợp và báo cáo
- Nhà nghiên cứu đã hợp tác với các nhà nghiên cứu bảo mật khác để xác minh lỗ hổng
- Ngay sau khi nhận được báo cáo, Discord đã vô hiệu hóa toàn bộ tài liệu dành cho nhà phát triển trong 2 giờ, sau đó quay lại nền tảng cũ
- Sau khi biết về lỗ hổng thông qua Discord, Mintlify đã mở một kênh Slack giữa đội ngũ kỹ thuật và các nhà nghiên cứu để lập tức tiến hành khắc phục
Phạm vi ảnh hưởng
- Phần lớn khách hàng của Mintlify như X(Twitter), Vercel, Cursor, Discord đều nằm trong vùng ảnh hưởng
- Trên tên miền chính thức của từng công ty, chỉ một liên kết độc hại cũng có thể dẫn đến nguy cơ chiếm đoạt tài khoản
- Một lỗ hổng duy nhất trong chuỗi cung ứng có thể gây ra rủi ro dây chuyền cho bảo mật của hàng trăm công ty
Phần thưởng và kết luận
- Nhóm nghiên cứu đã nhận tổng cộng khoảng 11.000 USD tiền thưởng bug bounty
- Discord trả 4.000 USD, Mintlify chi trả thêm cho từng lỗ hổng riêng lẻ
- Đây là một trường hợp tiêu biểu cho thấy tầm quan trọng của bảo mật chuỗi cung ứng và mức độ lan rộng của lỗ hổng trên một nền tảng đơn lẻ
1 bình luận
Ý kiến trên Hacker News
Đây thực sự là một ví dụ exploit rất đáng sợ
Chỉ cần nhấp vào một liên kết duy nhất, ví dụ như https://discord.com/_mintlify/static/evil/exploit.svg, là JavaScript sẽ chạy trên tên miền Discord
Kết quả là cookie phiên hoặc token có thể bị đánh cắp, tài khoản có thể bị chiếm hoàn toàn, rồi ứng dụng dành cho nhà phát triển hay webhook bị thao túng, hoặc máy chủ bị xóa qua API, thậm chí thông tin thanh toán bị lợi dụng để mua Nitro, nên mức độ thiệt hại là rất lớn
Xét quy mô thiệt hại như vậy thì bug bounty $4.000 có cảm giác là phần thưởng quá ít
Nếu luôn đặt cookie phiên ở chế độ HTTP-only thì sẽ chống chịu tốt hơn nhiều trước kiểu tấn công này
Thật ngạc nhiên là có nhiều lập trình viên frontend vẫn không biết những khái niệm bảo mật cơ bản như vậy
Ở chợ đen, nó hẳn đã có giá trị cao hơn nhiều
Tôi cho rằng ngay từ đầu việc cho phép nhúng script vào file SVG đã là một sai lầm về bảo mật
Việc có thể làm demo tương tác hoặc game chỉ bằng một file SVG thì rất ngầu, nhưng cũng khiến nó trở thành ổ phát sinh lỗ hổng
Vì vậy nhiều nền tảng cấm tải lên SVG hoặc chặn xem trước
Ngay cả trên Discord, khi tải SVG lên thì mã sẽ hiện nguyên văn, còn trên Facebook Messenger hay WeChat cũng không thể chia sẻ được
Dù có ưu điểm là kích thước file nhỏ và không phụ thuộc độ phân giải, thật đáng tiếc khi định dạng ảnh raster vẫn được dùng rộng rãi hơn
Active Storage của Rails mặc định không sanitize SVG, nên cần cẩn thận
Xem thêm tài liệu OWASP
<script>hay khôngNhưng chỉ như vậy có lẽ vẫn chưa đủ
Với định dạng raster thì gần như không có chuyện đó
Vụ việc này dường như cho thấy một mặt cắt của hệ sinh thái startup AI hiện nay
Một startup làm tài liệu AI lớn lên nhờ vốn VC có được khách hàng lớn mà không qua kiểm chứng bảo mật, và cuối cùng đẩy hàng triệu người vào rủi ro
Mintlify gần đây còn viết blog khoe kiến trúc cache phức tạp, nhưng trên thực tế dường như lại không nắm nổi cả bảo mật cơ bản
Trong tình huống như vậy, người phát hiện lỗ hổng chỉ nhận được vỏn vẹn $5.000
Tôi nghĩ đây là một ví dụ cho thấy văn hóa phát triển dựa trên AI hiện nay mong manh đến mức nào
Chuỗi phụ thuộc phức tạp và địa ngục DLL của nhiều bên thứ ba mới là nguyên nhân gốc rễ
Nếu Discord không phục vụ tài liệu API trực tiếp từ discord.com thì đã không có chuyện này
Chẳng phải chỉ CDN là đủ sao
Đây là lỗi có thể dẫn đến chiếm trọn tài khoản khách hàng, vậy mà mức thưởng quá thấp
Thời nay không có lý do gì để vẫn cho phép XSS tồn tại
Ngay cả Anubis năm nay cũng đã phát hiện hai lỗi reflected XSS
Phụ thuộc bên thứ ba nhất định phải được kiểm tra
Xem thông báo bảo mật liên quan ở đây và ở đây
Vì ngoài các mạng xã hội lớn ra thì thường khó kiếm lợi nhuận tài chính từ nó
Tôi nghĩ hay là thuê luôn hacker 16 tuổi đã tìm ra lỗ hổng này làm chính thức hoặc bán thời gian để kiểm tra bảo mật thường trực
Chỉ cần trả $50.000 mỗi năm thôi cũng có vẻ sẽ giúp bảo mật của công ty được nâng cấp đáng kể
Bug bounty trả thưởng theo kết quả nên hiệu quả hơn
Tuy vậy, nếu mức thưởng thấp thì nhà nghiên cứu sẽ dễ bị cám dỗ bán cho bên thứ ba
Mỗi người có lĩnh vực riêng như XSS, IAM, shell exploit..., nên một người khó mà bao quát hết mọi thứ
Thật ấn tượng khi một người 16 tuổi lại phát hiện ra chuyện này
Nhưng gọi XSS là tấn công chuỗi cung ứng (supply chain attack) thì nghe vẫn hơi lạ
Nếu sự cố xảy ra ở tầng trung gian như Mintlify thì người dùng cuối hoàn toàn không có cách phòng vệ
Mã độc được chuyển đi bên trong một chuỗi tin cậy, nên cũng có thể xem là một dạng XSS ở cấp độ chuỗi cung ứng
Báo cáo của cộng tác viên còn bao gồm cả lỗ hổng RCE nghiêm trọng hơn
Xem chi tiết trong blog này
Nhìn những trường hợp như thế này thì,
1️⃣ Content Security Policy (CSP) nhất định phải được thiết lập
2️⃣ Trên máy chủ NodeJS nên dùng mặc định tùy chọn
--disallow-code-generation-from-stringsCác nhà cung cấp dịch vụ như Vercel nên hiện cảnh báo khi không dùng CSP
Ngoài ra, các cờ bảo mật NodeJS đáng tham khảo khác được tổng hợp trong bài viết này
Proxy sang dịch vụ bên thứ ba ngay trên tên miền chính có gắn xác thực người dùng là lựa chọn tệ nhất
Đáng lẽ Mintlify phải được tách sang một subdomain riêng như dev-docs.discord.com
Dù khách hàng có muốn thì rủi ro bảo mật cũng quá lớn
Tuy vậy, vì SEO nên có rất nhiều nhu cầu muốn đặt tài liệu trên tên miền chính
Ở góc độ Mintlify, chuyện này chắc hẳn cũng rất căng thẳng
Cần dùng subdomain riêng cho bên thứ ba, và cookie xác thực của ứng dụng chính phải bị giới hạn ở chế độ host-only
Nếu có thể thì dùng hẳn một tên miền khác hoàn toàn, ví dụ
discorddocs.com, sẽ an toàn hơnNhưng so với rủi ro bảo mật thì đây là một lựa chọn quá nguy hiểm
Từ giờ tôi sẽ không bao giờ mở file SVG nữa
Một người 16 tuổi mà tìm ra được chuyện này thì đúng là huyền thoại