How we prevented security fixes leaking into our public repositories
Bài tóm tắt GitLab 2021 3. Quy mô lớn Độ khó: Trung bình
GitLab · 2021 · 3. Quy mô lớn · Độ khó: Trung bình — bài gốc
Bối cảnh
- GitLab làm việc "công khai mặc định", trừ bản vá bảo mật (làm công khai là lộ lỗ hổng trước khi có bản vá). Mỗi project công khai có một fork Security riêng tư; repo công khai (Canonical) được push mirror sang fork đó để người sửa lỗi luôn làm trên code mới nhất. Mirroring do Gitaly (server xử lý mọi lời gọi Git) thực hiện.
- Để biết object nào bên đích còn thiếu, GitLab
fetchremote rồi mới push. Hệ quả: mọi object của repo Security được lưu trên đĩa của repo công khai. Ai biết SHA của commit vá lỗi là xem được nó trong repo công khai. - SHA khó đoán, nhưng trang Help của GitLab.com hiện SHA đang chạy, và GitLab luôn deploy bản vá lên GitLab.com trước để kiểm. Trong lúc làm security release, bất kỳ user đăng nhập nào cũng bấm vào SHA đó và xem toàn bộ cây mã, kể cả bản vá.
Thay đổi chính
- Tạm thời: dừng mirroring ngay khi bản vá được merge, bật lại khi release xong. Hết rò, nhưng "dừng thế giới": fork Security tụt lại, dễ xung đột giữa tính năng mới và bản vá. Phương án ẩn SHA khỏi trang Help bị loại vì chỉ là che giấu.
- Nguyên nhân gốc: một staff engineer nhận ra branch dùng
fetchcòn tag thì dùngls-remote(chỉ liệt kê ref, không tải object). Dùngls-remotecho cả branch thì commit của mirror không còn nằm trên đĩa repo công khai. - Đổi thận trọng vì mirroring là đường găng:
- Thí nghiệm: giữ nguyên hành vi cũ, khi bật feature flag thì lấy thêm thông tin bằng
ls-remote, so với kết quả cũ, log khác biệt. Chạy trên GitLab.com khoảng một tháng, không có khác biệt lớn. - Tách hai đường theo flag: tắt là đường cũ, bật là đường mới; bật và theo dõi hai tuần.
- Bản self-managed phát hành với flag bật mặc định (dễ lùi nếu hỏng), rồi xoá flag và đường cũ.
- Thí nghiệm: giữ nguyên hành vi cũ, khi bật feature flag thì lấy thêm thông tin bằng
- Lỗi phụ sau khi đổi: email báo push mirror hỏng nhưng kiểm lại thì bình thường, kéo dài khoảng hai tháng; thành vấn đề thật khi một công cụ mới dựa vào trạng thái mirror. Thêm log thì thấy repo nhận (Security) có vẻ đi trước repo nguồn: với số branch/tag rất lớn,
ls-remotechạy lâu tới mức trong lúc đó repo nguồn đã nhận push mới, làm danh sách ref local (lấy trước) lỗi thời. Sửa bằng cách đảo thứ tự: lấy ref remote trước, local sau.
Vì sao
- Theo GitLab, đổi một chức năng găng như mirroring cần bằng chứng từ traffic thật (chạy song song, so sánh) trước khi thay, và cần đường lùi ở từng bước.
Bài học cho SWE
- Một thao tác "chỉ để so sánh" (
fetch) có thể có tác dụng phụ bảo mật: dữ liệu riêng tư bị kéo sang nơi công khai. - Khi so hai ảnh chụp trạng thái lấy ở hai thời điểm, thứ tự lấy quyết định có race hay không: lấy cái chậm hoặc cái ít đổi trước.
- Mẫu đổi hành vi an toàn: chạy bóng và so (shadow) → flag tách đường → bật mặc định có đường lùi → xoá code cũ.
Liên quan
- GitLab 2019 · Stripe 2026 (so bản cũ và mới trên dữ liệu thật) · Rust 2026 (rò qua hạ tầng phụ)
- Bảo mật hạ tầng và quản lý secret · Deploy và release an toàn
#Push mirror#Security fork#Gitaly#git fetch vs ls-remote#Feature flag#Experiment#Race condition#Security release
Được nhắc tới trong
Công ty (1)
Bài tóm tắt (3)