Lỗ hổng XSS trong ansi2html cho phép chiếm đoạt tài khoản SourceHut qua nhật ký build
Một nhà nghiên cứu bảo mật đã phát hiện lỗ hổng XSS trong thư viện ansi2html, cho phép kẻ tấn công chèn mã độc vào nhật ký build của SourceHut và chiếm đoạt tài khoản người dùng. Lỗ hổng tồn tại gần 4,5 năm trước khi được vá, ảnh hưởng đến các phiên bản ansi2html từ 1.7.0 trở lên.
Lỗ hổng XSS trong ansi2html cho phép chiếm đoạt tài khoản SourceHut qua nhật ký build
Một nhà nghiên cứu bảo mật đã công bố chi tiết về lỗ hổng XSS (Cross-Site Scripting) nghiêm trọng trong thư viện ansi2html — công cụ chuyển đổi mã màu ANSI sang HTML được SourceHut sử dụng để hiển thị nhật ký build. Lỗ hổng này cho phép kẻ tấn công chèn mã JavaScript độc hại vào nhật ký build, từ đó chiếm đoạt tài khoản và truy cập vào các deploy key quan trọng của hệ thống CI/CD.
Lỗ hổng tồn tại trong gần 4,5 năm trước khi được vá, và các phiên bản bị ảnh hưởng bao gồm ansi2html từ 1.7.0 trở lên.
Bối cảnh: SourceHut và kiến trúc microservices
SourceHut (sr.ht) là một nền tảng lưu trữ mã nguồn và CI/CD mã nguồn mở, được thiết kế theo kiến trúc microservices với nhiều dịch vụ riêng biệt:
- meta.sr.ht: quản lý tài khoản người dùng
- git.sr.ht: lưu trữ kho Git
- builds.sr.ht: hệ thống CI/CD chạy build
- hub.sr.ht: giao diện tổng hợp
- lists.sr.ht: danh sách mailing list
Điểm đáng chú ý là SourceHut có thể hoạt động tốt không cần JavaScript, đây là một triết lý thiết kế cốt lõi của nền tảng này.
Phát hiện lỗ hổng
Nhà nghiên cứu tình cờ phát hiện ra vấn đề khi đang xem mã nguồn trang nhật ký build và nhận thấy các quy tắc CSS bị lặp lại vô số lần. Khi tìm hiểu sâu hơn về logic chuyển đổi mã ANSI sang HTML, anh phát hiện ra rằng ansi2html xử lý không đúng các liên kết OSC 8 (siêu liên kết trong terminal).
Bằng cách chèn chuỗi thoát ANSI độc hại, kẻ tấn công có thể tạo ra mã HTML thực thi JavaScript:
Chuỗi
␛]8;;https://example.com/"/autofocus/tabindex="1"/onfocus="alert\xss`␇khi được xử lý sẽ tạo ra thẻ HTML có thuộc tínhautofocusvàonfocus`, kích hoạt mã JavaScript ngay khi trang được tải.
Đáng chú ý, kẻ tấn công không cần tài khoản trả phí để khai thác lỗ hổng này — chỉ cần gửi một patch đến mailing list công khai có bật CI, hoặc kiểm soát bất kỳ tài nguyên từ xa nào được in ra nhật ký.
Kịch bản tấn công
Khi nạn nhân (bao gồm cả quản trị viên) truy cập trang nhật ký build bị nhiễm độc, mã JavaScript sẽ thực thi trong trình duyệt của họ. Kẻ tấn công có thể:
- Đọc CSRF token có sẵn trong trang nhật ký build thông qua
document.querySelector('[name=_csrf_token]').value - Gửi build job mới dưới danh nghĩa nạn nhân bằng cách tự động điền form
- Chiếm đoạt deploy key — đặc biệt nguy hiểm vì builds.sr.ht lưu trữ deploy key cho chính sr.ht
- Tự cấp quyền admin nếu nạn nhân là quản trị viên
Lỗ hổng này có tính wormable (có thể lây lan), khi nạn nhân trở thành trung gian tấn công người khác ngay lập tức, mở rộng phạm vi ảnh hưởng.
Điểm CVSS và mức độ nghiêm trọng
Nhà nghiên cứu đã đề xuất điểm CVSS 4.0 với các thông số đáng chú ý:
- AV:N — vector tấn công qua mạng
- AC:L — độ phức tạp tấn công thấp
- PR:N — không yêu cầu quyền hạn
- UI:P — yêu cầu tương tác thụ động (nạn nhân chỉ cần truy cập trang có JS)
- VC:H, VI:H — ảnh hưởng cao đến tính bảo mật và toàn vẹn
- AU:Y — có thể tự động hóa (wormable)
"Nếu tôi là kẻ tấn công mũ đen, chỉ cần Drew truy cập một nhật ký build bị ảnh hưởng với JS bật, tôi có thể gửi build job dưới tên anh ấy với quyền truy cập deploy key của SourceHut."
Theo tác giả, mức độ nghiêm trọng nên được đánh giá là cao hoặc nghiêm trọng, không chỉ ở mức trung bình.
Quá trình khắc phục
Sau khi nhận được báo cáo, Drew DeVault (người sáng lập SourceHut) đã nhanh chóng vá builds.sr.ht bằng cách tự động làm sạch (sanitize) đầu ra từ ansi2html. Tuy nhiên, biện pháp này được cho là "quá nghiêm ngặt" vì nó loại bỏ luôn cả màu sắc trong nhật ký build.
Về phía upstream, thư viện ansi2html nằm dưới tổ chức pycontribs trên GitHub. Nhà nghiên cứu đã liên hệ với các maintainer, và sau nhiều lần trì hoãn, phiên bản 1.9.4 được phát hành với bản vá chính thức vào ngày 2 tháng 9.
Mốc thời gian chính:
- 2021-09-03: Lỗ hổng được đưa vào upstream ansi2html
- 2022-02-08: Phiên bản bị ảnh hưởng được đóng gói cho Alpine
- 2022-07-10: Phiên bản bị ảnh hưởng được đóng gói cho Arch Linux
- 2026-08-01: Nhà nghiên cứu gửi báo cáo lỗ hổng
- 2026-08-04: Lỗ hổng được giảm thiểu trong builds.sr.ht
- 2026-09-02: Phiên bản 1.9.4 vá lỗ hổng được phát hành
- 2026-09-05: Arch Linux cập nhật ansi2html lên bản đã vá
Bài học và khuyến nghị bảo mật
Sự việc này nhấn mạnh một số nguyên tắc quan trọng trong bảo mật:
Phòng thủ theo chiều sâu (Defense in Depth):
- Siết chặt Content-Security-Policy, đặc biệt là loại bỏ
'unsafe-inline' - Thêm lớp làm sạch bổ sung ở tầng ứng dụng
- Tái cấu trúc code ansi2html thành máy trạng thái có kiểm soát
Kiểm tra nhật ký build:
Nếu bạn đang sử dụng SourceHut hoặc hệ thống tương tự, hãy kiểm tra nhật ký build thô để tìm các mẫu đáng ngờ:
# Tìm kiếm liên kết OSC 8 độc hại
grep $'\33]8;[^\7\33]*"' build.log
# Hoặc kiểm tra liên kết javascript:
grep $'\33]8;;javascript:' build.log
Đối với nhà phát triển Việt Nam:
Nếu bạn đang tự vận hành instance SourceHut hoặc sử dụng ansi2html trong dự án của mình, hãy cập nhật ngay lên phiên bản 1.9.4 trở lên. Đây là lời nhắc nhở về tầm quan trọng của việc theo dõi các dependency bên thứ ba — ngay cả những thư viện nhỏ như ansi2html cũng có thể trở thành lỗ hổng nghiêm trọng trong hệ thống lớn.
"Ngay cả việc kiểm tra ansi2html một cách cẩn thận cũng không cứu được SourceHut, trừ khi việc đó được thực hiện lại sau mỗi lần cập nhật phiên bản."
Câu chuyện này cũng phản ánh thực trạng chung: nhiều dự án mã nguồn mở quan trọng phụ thuộc vào các thư viện nhỏ, ít được bảo trì, và một lỗ hổng đơn lẻ có thể gây ảnh hưởng dây chuyền đến toàn bộ hệ sinh thái.


