- Chỉ với lỗi trong giao thức nội bộ trên đường đi của
git push, có thể thực hiện thực thi mã từ xa ở backend; GitHub.com đã được giảm thiểu, nhưng GHES vẫn cần áp dụng bản vá
- Push option do người dùng kiểm soát được đưa nguyên vào header
X-Stat, nên chỉ với một dấu chấm phẩy đã có thể chèn trường mới, và cơ chế last-write-wins nơi giá trị xuất hiện sau ghi đè giá trị trước của cùng một khóa đã bị khai thác
- Bằng cách kết hợp các trường có thể chèn là
rails_env, custom_hooks_dir, repo_pre_receive_hooks, có thể vượt qua sandbox và thực thi hook ở đường dẫn do kẻ tấn công chỉ định với quyền người dùng git
- Cùng cơ chế đó còn cho phép chèn cả cờ enterprise mode trên GitHub.com, dẫn tới xác nhận thực thi mã trên shared storage node, rồi tiếp tục cho phép đọc cả kho lưu trữ của người dùng và tổ chức khác trên node đó
- Trường hợp này cho thấy trong kiến trúc đa dịch vụ, nơi các dịch vụ khác nhau cùng tin tưởng vào một định dạng dùng chung, việc thiếu làm sạch đầu vào, tồn tại đường thực thi phi production và thiếu kiểm tra đường dẫn có thể kết hợp thành một lỗ hổng nghiêm trọng
Ứng phó ngay và phạm vi ảnh hưởng
- Trên GitHub.com, vấn đề này đã được giảm thiểu và không cần thêm hành động
- GitHub Enterprise Server cần ứng phó ngay; phải nâng cấp lên GHES 3.19.3 trở lên có bao gồm bản sửa cho
CVE-2026-3854
- Phạm vi phiên bản dễ bị ảnh hưởng là GHES 3.19.1 trở xuống; các phiên bản đã sửa được nêu là
3.14.24, 3.15.19, 3.16.15, 3.17.12, 3.18.6, 3.19.3
- Tính đến thời điểm bài viết được soạn, 88% instance GHES vẫn còn ở trạng thái dễ bị tấn công
- Có thể xem thêm thông tin kỹ thuật và quy trình khôi phục từ GitHub tại GitHub Security Blog
- Khách hàng Wiz có thể dùng truy vấn dựng sẵn của Wiz Threat Center để xác định các instance GHES dễ bị ảnh hưởng
Bối cảnh điều tra và cách tiếp cận
- Hạ tầng git nội bộ của GitHub là đường xử lý mọi
git push, gồm nhiều dịch vụ nội bộ được viết bằng các ngôn ngữ lập trình khác nhau
- Trong cấu trúc đa dịch vụ kiểu này, khác biệt trong cách mỗi thành phần phân tích và tin tưởng dữ liệu dùng chung có thể dẫn tới lỗ hổng
- Trước đây, việc trích xuất và kiểm toán khối lượng lớn binary black-box đã biên dịch cấu thành pipeline này đòi hỏi quá nhiều thời gian và công sức thủ công
- Với công cụ tăng cường bằng AI và reverse engineering tự động dựa trên
IDA MCP, có thể nhanh chóng phân tích binary đã biên dịch và tái dựng giao thức nội bộ
- Trong quá trình đó, nhóm nghiên cứu lần theo có hệ thống những điểm mà đầu vào người dùng có thể ảnh hưởng đến hành vi máy chủ trong toàn pipeline, và phát hiện ra lỗi mang tính nền tảng trong luồng đầu vào
Kiến trúc nội bộ và ranh giới tin cậy
- Khi
git push đi vào qua SSH, yêu cầu sẽ đi qua babeld, gitauth, gitrpcd, rồi đến pre-receive hook
babeld là điểm vào của mọi thao tác git, nhận kết nối SSH và chuyển việc xác thực sang gitauth
gitauth kiểm tra thông tin xác thực người dùng và quyền push vào kho lưu trữ, rồi trả về các chính sách bảo mật như giới hạn kích thước tệp hoặc quy tắc đặt tên nhánh
- Dựa trên phản hồi này,
babeld tạo header nội bộ X-Stat chứa metadata bảo mật
gitrpcd nhận header X-Stat để thiết lập môi trường cho các tiến trình tiếp theo, và hoàn toàn tin tưởng babeld mà không tự xác thực
- Pre-receive hook kiểm tra giới hạn kích thước tệp, quy tắc tên nhánh, tính toàn vẹn LFS và các custom hook do quản trị viên định nghĩa trước khi chấp nhận push
- Mắt xích cốt lõi là header X-Stat chứa các cặp
key=value được phân tách bằng ;
- Các dịch vụ nội bộ tách
X-Stat theo ; rồi nạp vào map; nếu cùng một khóa xuất hiện hai lần thì giá trị đến sau sẽ ghi đè giá trị trước theo quy tắc last-write-wins
babeld cũng đưa push options truyền qua git push -o vào X-Stat dưới dạng các trường như push_option_0, push_option_1, push_option_count
Nguyên nhân lỗ hổng: chèn trường X-Stat
babeld sao chép giá trị push option do người dùng kiểm soát vào header X-Stat mà không xử lý dấu chấm phẩy
- Vì
; là ký tự phân tách trường của X-Stat, chỉ cần một dấu chấm phẩy trong push option là có thể thoát khỏi trường gốc để tạo ra trường do kẻ tấn công kiểm soát
- Ví dụ, nếu chèn
large_blob_rejection_enabled=bool:false vào bên trong push_option_0, thì giá trị bool:true được đặt trước đó sẽ bị giá trị đến sau ghi đè
- Hành vi này được xác nhận cả qua phân tích binary lẫn packet capture trên instance GHES thực tế
- Kết hợp reverse engineering với phân tích ở mức wire giúp lập bản đồ các trường
X-Stat có thể bị chèn
- Đặc biệt, các trường nhạy cảm về bảo mật được xác nhận gồm
rails_env, custom_hooks_dir, repo_pre_receive_hooks, large_blob_rejection_enabled, reject_sha_like_refs, user_operator_mode
- Trong số đó, ba trường
rails_env, custom_hooks_dir, repo_pre_receive_hooks là chìa khóa dẫn tới thực thi mã từ xa
Con đường dẫn tới RCE trên GHES
- GHES hỗ trợ custom pre-receive hooks được chạy trước khi chấp nhận push
- Binary pre-receive có hai đường thực thi được phân nhánh chỉ dựa trên giá trị
rails_env trong X-Stat
- Nếu giá trị là
production, hook sẽ được chạy trong sandbox; còn với giá trị khác, nó sẽ được chạy trực tiếp với quyền người dùng dịch vụ git, không có sandbox hay cô lập
- Vì vậy, chèn
rails_env thành giá trị phi production sẽ cho phép vượt qua sandbox
- Tiếp theo, chèn
custom_hooks_dir cho phép kẻ tấn công kiểm soát thư mục gốc dùng để tìm script hook
- Cuối cùng, nếu chèn vào
repo_pre_receive_hooks một định nghĩa hook chứa path traversal, thì quá trình phân giải đường dẫn của binary sẽ kết hợp thư mục do kẻ tấn công kiểm soát với payload traversal để trỏ tới đường dẫn tùy ý trên filesystem
- Đường thực thi phi production sau đó sẽ chạy trực tiếp đường dẫn đã được phân giải này, không đối số, không sandbox, dưới quyền người dùng dịch vụ
git
- Trong thử nghiệm thực tế, chỉ với một lần
git push, đầu ra uid=500(git) đã được trả về, xác nhận RCE với quyền người dùng git
- Với quyền này, có thể giành toàn quyền kiểm soát gồm đọc/ghi filesystem của instance GHES và quan sát cấu hình các dịch vụ nội bộ
Mở rộng sang GitHub.com và lộ dữ liệu chéo tenant
- Khi áp dụng cùng chuỗi khai thác cho kho GitHub.com, ban đầu push vẫn thành công nhưng custom hooks không được thực thi
- Sau khi chèn
user_operator_mode=bool:true và so sánh đầu ra debug giữa hai nền tảng, nhóm nghiên cứu xác định rằng trên GitHub.com, luồng mã của custom hooks không được chạm tới
- Reverse engineering thêm cho thấy trong header
X-Stat có một cờ boolean điều khiển việc máy chủ có hoạt động ở enterprise mode hay không
- Trên GHES, cờ này mặc định là true nên đường custom hooks luôn được kích hoạt; còn trên GitHub.com, giá trị mặc định là false nên bình thường sẽ không vào nhánh đó
- Vì cờ này cũng có thể bị chèn bằng cùng cơ chế, chỉ cần chèn thêm một trường là toàn bộ chuỗi khai thác đã hoạt động được trên GitHub.com
- Sau đó, kết quả chạy
hostname từ bên trong hạ tầng GitHub.com đã được trả về, xác nhận RCE trên GitHub.com
- GitHub.com là nền tảng multi-tenant, nơi kho lưu trữ của nhiều người dùng và tổ chức cùng được lưu trên hạ tầng backend dùng chung
- Vị trí xảy ra thực thi mã là một shared storage node, nơi người dùng
git có quyền filesystem rất rộng để xử lý mọi thao tác kho lưu trữ trên node đó
- Nếu tài khoản này bị xâm phạm, kho lưu trữ của các tổ chức và người dùng khác trên cùng node cũng có thể bị đọc mà không liên quan đến chủ sở hữu
- Khi liệt kê các mục chỉ mục kho lưu trữ có thể truy cập trên hai node bị xâm phạm, mỗi node có hàng triệu entry, bao gồm kho của những người dùng và tổ chức khác
- Nhóm nghiên cứu không truy cập nội dung thực tế của kho thuộc tenant khác; họ chỉ dùng tài khoản thử nghiệm của mình để xác minh rằng quyền filesystem của người dùng
git cho phép đọc mọi kho lưu trữ trên node
Bài học chính và mốc công bố
- Chỉ với một lần
git push, có thể khai thác lỗi trong giao thức nội bộ để thực hiện thực thi mã từ xa trên hạ tầng backend
- Khi nhiều dịch vụ viết bằng các ngôn ngữ khác nhau trao đổi dữ liệu qua một giao thức nội bộ dùng chung, chính giả định tin cậy của từng dịch vụ sẽ trở thành bề mặt tấn công
- Trong chuỗi này, một dịch vụ đã chèn nguyên giá trị push option, dịch vụ khác lại tin tưởng mọi trường trong
X-Stat, còn pre-receive hook thì giả định rằng trong môi trường vận hành rails_env sẽ luôn là production
- Đường mã phi production trong binary vận hành, thiếu kiểm tra path traversal cho script hook và thiếu làm sạch đầu vào trong giao thức dựa trên ký tự phân tách là những mẫu lỗi có thể xuất hiện ở nhiều codebase khác
- Các nhóm vận hành kiến trúc đa dịch vụ đặc biệt cần kiểm tra cách đầu vào do người dùng kiểm soát đi qua giao thức nội bộ ra sao, nhất là khi các thiết lập nhạy cảm về bảo mật được suy ra từ định dạng dữ liệu dùng chung
- Trong nghiên cứu này, các công cụ reverse engineering tăng cường bằng AI gồm cả
IDA MCP đã giúp phân tích binary đã biên dịch và tái dựng giao thức nội bộ nhanh hơn nhiều
- Khi những công cụ này trưởng thành hơn, chúng có thể sẽ đóng vai trò ngày càng quan trọng trong việc tìm ra các nhóm lỗ hổng đòi hỏi phân tích sâu xuyên thành phần
- Theo mốc thời gian công bố, vào
2026-03-04 nhóm nghiên cứu phát hiện lỗ hổng chèn push option vào X-Stat, cùng ngày xác nhận RCE trên GHES 3.19.1 và báo cho GitHub; bản sửa cho GitHub.com cũng được triển khai trong ngày đó
- Đến
2026-03-10, lỗ hổng được gán CVE-2026-3854 và CVSS 8.7, đồng thời bản vá cho GHES được công bố
- Vào
2026-04-28, lỗ hổng được công khai
1 bình luận
Ý kiến trên Hacker News
Về cơ bản họ đã để chuỗi tùy ý do người dùng cuối đưa vào qua
git push -ocùng chui vào header bảo mật cốt lõi do dịch vụ xác thực nội bộ thiết lậpNói sau thì dễ, nhưng chuyện này vẫn quá sức khó tin
Cách reverse engineering được tăng cường bằng AI này cho thấy rất rõ điểm mạnh hiện tại của các agent LLM
Với các mô hình được huấn luyện nhiều trên code, chúng có thể tăng tốc rất mạnh việc hiểu nội tình của những hệ thống phức tạp
Nghiên cứu bảo mật thường là sự chồng lấn giữa 1) tìm hiểu cơ chế nội bộ phức tạp và 2) tìm lỗ hổng trong đó,
và không ít khi chỉ cần lộ ra cơ chế bên trong thật sự thì bản thân lỗ hổng lại hiện ra khá dễ
CVE-2026-3854 không phải kiểu mà biết nội tình là thấy ngay,
nhưng nếu nó lộ ra trên một bề mặt tấn công truyền thống hơn hoặc dễ tiếp cận hơn thì lệnh chèn này hẳn đã bị phát hiện rất nhanh
Nhưng dạo gần đây có cảm giác xu hướng đó bị chệch đi, hoặc thậm chí bị cản trở có chủ đích bởi những bên muốn giữ nguyên kiểu dev/vendor lock-in sinh ra từ độ phức tạp cú pháp của C++
Gần như khiến người ta tự hỏi có ai từ Wiz đang ở đó không, vì kết quả trông khá ấn tượng
Sản phẩm của họ dù tăng trưởng cực mạnh và phình to tính năng vẫn còn trụ khá tốt,
và đội bảo mật cũng thường xuyên tìm ra những thứ thật sự thú vị
osv-scannervàtrivyđể chỉ xem các mức criticaltrong khi các thao tác đáng ngờ hơn như truy vấn DC bằng CLI rồi reset thông tin xác thực lại im lặng, nên khá hụt hẫng
Khi
babeldchuyển tiếp yêu cầu push, nó đưa các push option vào header X-Stat của yêu cầu nội bộ,và giá trị đó là chuỗi tùy ý do người dùng nhập qua
git push -oNhưng họ lại sao chép nguyên giá trị mà không sanitize dấu chấm phẩy,
và vì
;là ký tự phân tách trường trong X-Stat nên nó cho phép kẻ tấn công thoát khỏi trường gốc và tạo trường mớiĐúng kiểu mắc lỗi đơn giản nhất có thể, như thể trái cây đã thấp đến mức chui xuống dưới đất rồi
Dù đây là lỗ hổng được phát hiện trước khi bị khai thác,
tôi vẫn tự hỏi có cần phải khuếch đại nỗi sợ bằng những cụm như BREAKING, unauthorized access, millions of repositories hay không
https://x.com/wiz_io/status/2049153209982140718
GitHub chỉ là đã may mắn vì bên phát hiện ra là fuzzing của Wiz, chứ không phải một tác nhân được nhà nước hậu thuẫn
Việc 88% instance GHES vẫn chưa áp dụng bản vá bảo mật nghiêm trọng phát hành từ 7 tuần trước trông khá đáng lo
https://docs.github.com/en/enterprise-server@3.19/admin/release-notes#3.19.3
Chỉ để áp dụng một bản phát hành mức patch cũng cần vài giờ downtime,
lại còn không có cách nâng cấp HA được hỗ trợ, nên ngay cả khách hàng chăm cập nhật cũng khó bám kịp bản mới
Hễ phàn nàn là ai cũng bảo chuyển sang GitHub Enterprise Cloud,
nhưng thời buổi này có bao nhiêu người sẽ sẵn sàng chọn như vậy thì cũng đáng nghi
Dù sao GHES ít nhất còn có điểm là không chết giữa những đợt sự cố hàng ngày của github.com
và có vẻ đang đợi một ngày phù hợp hơn để nâng cấp với ít ảnh hưởng vận hành hơn
Tuy vậy, nếu là instance public thì nên cập nhật ngay
Chỉ với thông tin trong bài và mã nguồn GitHub Enterprise đã công khai cũng có vẻ không khó để dựng lại cách tái hiện
hoặc cứ đi theo lịch và hy vọng không có chuyện gì xảy ra; đa số thường chọn phương án sau
việc một sản phẩm on-prem chỉ được cập nhật mỗi năm một lần cũng chẳng có gì lạ
Với phần mềm enterprise có dữ liệu lớn, chỉ một chuyện rất nhỏ cũng có thể làm hỏng cả hệ thống cài đặt và đội vận hành phải rollback
Các đợt nâng cấp SharePoint ngày xưa gần như giống tung xúc xắc
Vụ này cũng là một chiến công lớn của Wiz,
và cho cảm giác như một bước ngoặt cho thấy công cụ AI có thể thúc đẩy RE và tìm đường xâm nhập mạnh đến đâu
Đây lại là thêm một điểm dữ liệu cho thấy bảo mật rốt cuộc không nên dựa vào security through obscurity
Ai cũng nói hãy thay GitHub đi, nhưng rồi lại vướng câu hỏi vậy dùng gì
Ngay cả một nơi cỡ GitHub mà giờ còn lộ RCE, thì cũng khó mà tự tin nói các lựa chọn khác sẽ tốt hơn
https://news.ycombinator.com/item?id=46961345
https://news.ycombinator.com/item?id=47712656
còn GitHub chỉ làm mirror trong thời gian tận dụng CI miễn phí
Secret thì giao cho một secret-hosting provider riêng
Đến giờ tôi vẫn khó tin là Forgejo lại phản hồi nhanh thế còn GitHub thì chậm đi nhiều như vậy
Project nội bộ để trên instance Forgejo private, còn project công khai đưa lên GitHub nhưng mirror sang Forgejo
Tôi đã khá ngạc nhiên vì Forgejo về cơ bản gần như là một binary duy nhất và cấu hình cũng dễ,
và vì mọi dịch vụ nội bộ đều đã trỏ vào Forgejo nên nếu phải rời GitHub thì ma sát cũng thấp
Chỉ cần image Docker all-in-one và vài GitLab runner là đủ cho các nhóm nhỏ đến trung bình,
trừ khi thật sự cần thì không có lý do gì phải phức tạp hóa đến mức dùng bản Kubernetes
Việc AI tìm lỗ hổng trong mã nguồn đã đủ ấn tượng,
nhưng làm được cả với file thực thi nhị phân thì thật sự đáng kinh ngạc
Tiềm năng theo cả hướng tốt lẫn xấu đều rất lớn
Và một lần nữa, bài học rằng không được đối xử dữ liệu như mệnh lệnh lại hiện ra
Mọi đầu vào từ người dùng đều phải được sanitize
Vì vậy việc nó mạnh ở source-to-source hay text-to-source vốn đã là câu chuyện quen thuộc,
nên chuyện nó cũng hợp để hiểu các phiên bản asm có thể không hẳn là điều quá bất ngờ
Dù vậy, nó vẫn rất ấn tượng
Tôi tò mò liệu có thể xác định được vụ này đã bị khai thác thật hay chưa
Có thể phần nào kiểm tra việc khai thác qua log HTTP/git protocol,
nhưng rất có thể sẽ không lưu được chính xác ai đã truy cập cái gì
Nếu exploit có thể chạy độc lập trên máy chủ git, thì theo định nghĩa nó có thể tránh được việc ghi log