Báo cáo kiểm toán Homebrew
(blog.trailofbits.com)- Cuộc kiểm toán của Trail of Bits xác nhận khả năng thực thi mã ngoài dự kiến và suy giảm tính toàn vẹn bản dựng trong Homebrew, trình quản lý gói gần như là tiêu chuẩn thực tế của hệ sinh thái nhà phát triển macOS; tuy nhiên các phát hiện không ở mức nghiêm trọng
- Phạm vi bao gồm Homebrew/brew với CLI
brew, cùng Homebrew/actions, Homebrew/formulae.brew.sh và Homebrew/homebrew-test-bot, tức xem xét đồng thời ranh giới giữa trình quản lý gói cục bộ và CI/CD - Các vấn đề ở phía
brewdẫn tới khả năng chèn chuỗi vào cấu hình sandbox, va chạm namespace dựa trên MD5, nhúng tài nguyên mạng không khai báo, pivot qua socket trên macOS, lạm dụng tokensudo, và cài formula từ URL không cục bộ - Trong CI/CD, trigger
pull_request_targetvà đầu vàoworkflow_dispatchkhông được xác thực có thể trở thành con đường để can thiệp bản dựng bottle, lộ thông tin xác thực, leo thang đặc quyền và duy trì truy cập trên self-hosted GitHub Actions runner - Homebrew giả định formula là đáng tin cậy, nhưng vì bản thân formula là mã Ruby có thể thực thi và bề mặt API·CLI rộng, nên rất khó duy trì nhất quán các ranh giới cô lập và toàn vẹn
Phạm vi và đối tượng kiểm toán
- Trail of Bits đã tiến hành kiểm toán Homebrew vào mùa hè năm ngoái
- Đối tượng kiểm toán là Homebrew/brew chứa CLI
brewvà 3 kho lưu trữ lân cận quan trọng về bảo mật- Homebrew/actions: kho GitHub Actions tùy biến được dùng trên toàn bộ CI/CD của Homebrew
- Homebrew/formulae.brew.sh: codebase phụ trách chỉ mục JSON của các gói có thể cài đặt
- Homebrew/homebrew-test-bot: các tác vụ điều phối CI/CD cốt lõi và quản lý vòng đời của Homebrew
- Open Tech Fund tài trợ cuộc kiểm toán như một phần của hoạt động tăng cường bảo mật cho các thành phần cốt lõi của hạ tầng Internet
- Có thể xem toàn bộ báo cáo trong kho publications của Trail of Bits
Vì sao Homebrew quan trọng
- Homebrew tự nhận là “trình quản lý gói còn thiếu cho macOS hoặc Linux” và đóng vai trò là trình quản lý gói tiêu chuẩn thực tế đối với các nhà phát triển macOS
- Mỗi năm xử lý hàng trăm triệu lượt cài đặt gói, trong đó có cả các gói cốt lõi như Golang, Node.js và OpenSSL
- Tính toàn vẹn bản dựng của các gói này không chỉ ảnh hưởng tới Homebrew mà còn liên quan tới an ninh của toàn bộ hệ sinh thái phần mềm phía dưới
- Phần lõi của Homebrew là một Ruby monolith cung cấp CLI
brewvà API Ruby có thể tái sử dụng - Kể từ khi bắt đầu vào năm 2009, Homebrew đã nhiều lần thay đổi cấu trúc để tăng độ tin cậy và tính tiện dụng của gói
- Giới thiệu bottle là các bản dựng nhị phân
- Dùng bottle làm phương thức cài đặt mặc định thay cho bản dựng từ mã nguồn cục bộ
- Chỉ xây dựng bottle trong CI/CD để giảm ảnh hưởng từ máy phát triển bị xâm nhập
- Dù cách cài đặt ngày càng mang tính tĩnh hơn, codebase cốt lõi vẫn còn dấu vết của cấu trúc lịch sử là tải động các formula dựa trên DSL bằng mã Ruby do người dùng kiểm soát
Ranh giới tấn công được xem xét trong kiểm toán
- Xác minh liệu tác nhân cục bộ có thể kích hoạt thực thi ngoài dự kiến của formula DSL mà không cần
brew installrõ ràng hay không - Rà soát liệu chỉ với
brew tap, việc đánh giá formula của tap có thể diễn ra ngoài dự kiến hay không - Kiểm tra liệu
brew install foocó thể bị khiến cài một formula khác với mong đợi do nhầm lẫn hoặc va chạm namespace hay không - Cũng xác minh liệu formula đã cài cục bộ có thể âm thầm vượt qua hoặc làm suy yếu cơ chế cô lập bản dựng của Homebrew hay không
- Trong CI/CD, câu hỏi cốt lõi là liệu tác nhân quyền thấp có thể pivot sang quyền cao hơn, làm nhiễm bẩn bản dựng bottle, hoặc tạo persistence hay không
Các vấn đề được phát hiện trong CLI brew
- Trong codebase CLI
brew, đã phát hiện các vấn đề có thể làm suy yếu thuộc tính toàn vẹn và cô lập theo từng formula - Cũng xác nhận các đường dẫn cho phép nạp formula từ các nguồn ngoài dự kiến như URL từ xa
- Các phát hiện chính như sau
- TOB-BREW-2: formula có thể thay đổi cấu hình sandbox bằng chèn chuỗi, dẫn tới khả năng thoát sandbox
- TOB-BREW-5: Homebrew dùng hàm băm MD5 có thể va chạm cho
FormulaNamespace, một namespace tổng hợp, nên kẻ tấn công có thể gây nhầm lẫn lúc chạy giữa các formula - TOB-BREW-8: formula có thể âm thầm nhúng tài nguyên mạng vào bản dựng mà không khai báo trong stanza
resource - TOB-BREW-11: formula có thể dùng pivot qua socket trên macOS để thoát khỏi sandbox bản dựng
- TOB-BREW-12: formula có thể thực hiện leo thang đặc quyền cơ hội thông qua token
sudođang còn hiệu lực từ trước của người dùng - TOB-BREW-13:
brew installcó thể bị dẫn tới cài formula từ URL không cục bộ qua mọi giao thức mà phiên bảncurlđang dùng hỗ trợ, như SFTP hay SCP
- Homebrew/brew được kiểm thử rất rộng, nhưng do bề mặt API·CLI lớn và các hợp đồng hành vi cục bộ mang tính không chính thức, vẫn còn nhiều dư địa để kẻ tấn công tìm ra đường thực thi mã cục bộ ngoài sandbox
- Các đường này không nhất thiết phá vỡ tiền đề bảo mật cốt lõi của Homebrew là giả định formula đáng tin cậy, nhưng có thể bị lợi dụng thông qua formula độc hại hoặc việc nạp formula ngoài dự kiến từ đầu vào chưa được chuẩn hóa đầy đủ
Các vấn đề được phát hiện trong CI/CD của Homebrew
- Trong các workflow và action CI/CD của Homebrew cũng phát hiện những vấn đề có thể làm suy yếu tính toàn vẹn của việc thực thi CI/CD
- Xác nhận khả năng người dùng quyền thấp có thể pivot sang vị trí có quyền cao hơn hoặc giành persistence trên self-hosted GitHub Actions runner của Homebrew
- Các phát hiện chính như sau
- TOB-BREW-18: nhiều workflow CI/CD dùng trigger
pull_request_target, cho phép pull request từ bên thứ ba chạy mã trong ngữ cảnh kho upstream của Homebrew, có thể dẫn tới lộ thông tin xác thực hoặc can thiệp bản dựng bottle - TOB-BREW-23: nhiều workflow CI/CD cho phép chèn shell thông qua đầu vào
workflow_dispatchkhông được xác thực, dẫn tới di chuyển theo chiều dọc đối với người dùng quyền thấp có thể chạy workflow nhưng không thể sửa workflow
- TOB-BREW-18: nhiều workflow CI/CD dùng trigger
- Ngoài các vấn đề riêng của CI/CD, một số phát hiện liên quan tới
brewcũng quan trọng trong môi trường CI/CD- TOB-BREW-6: do thiếu sandboxing và cô lập khi giải nén archive, tác nhân CI quyền thấp có thể bị dẫn tới giải nén formula hoặc mã thực thi được tự động nạp và chạy, rồi pivot sang ngữ cảnh có quyền cao hơn
- TOB-BREW-13: có thể lợi dụng
brew installđể cài formula không nằm trong ngữ cảnh tin cậy được CI cấu hình sẵn, từ đó phục vụ thực thi mã tùy ý và pivot đặc quyền
- CI/CD của Homebrew đã trưởng thành và hiệu quả trong việc giảm các điểm cần con người can thiệp trong vòng đời gói, nhưng vẫn dựa vào những mẫu dễ bị lạm dụng thường thấy trong workflow GitHub Actions
- trigger workflow rủi ro
- trộn lẫn cấu hình, mã và dữ liệu thông qua mở rộng template
- Những mẫu này không nhất thiết cho phép hoàn toàn tác nhân bên ngoài giành persistence hoặc pivot, nhưng có thể bị người trong nội bộ quyền thấp như rogue maintainer lợi dụng để làm suy yếu các giả định về toàn vẹn và cô lập của CI/CD
Vì sao kiểm toán trình quản lý gói khó
- Các hệ sinh thái quản lý gói như Homebrew vốn được thiết kế để cài đặt và chạy mã bên thứ ba tùy ý, nên ranh giới kiểm toán rất khó xác định
- Sự phân biệt giữa thực thi mã được dự kiến và thực thi mã ngoài dự kiến nhìn chung cũng mang tính không chính thức và được định nghĩa khá lỏng lẻo
- Trong Homebrew, vấn đề này còn nổi bật hơn vì formula tự thân là mã Ruby có thể thực thi
- Trong quá trình kiểm toán, nhóm đã phối hợp chặt chẽ với các maintainer của Homebrew, Homebrew PLC và quản trị viên bảo mật Homebrew Patrick Linnane
1 bình luận
Ý kiến trên Hacker News
Tôi là tác giả bài viết này và cũng là một trong những người tham gia kiểm toán, nên có thể trả lời câu hỏi
Nếu khó tìm báo cáo kiểm toán gốc vì đó là liên kết gián tiếp, tôi cũng để lại một bản sao ở đây: https://github.com/trailofbits/publications/blob/eb9344f2261...
Công việc rất tuyệt, và đây đúng là kiểu rà soát có hệ thống mà tôi đang tìm kiếm ở những giải pháp mã nguồn mở như thế này
Có lẽ không phải trọng tâm của việc review code, nhưng tôi muốn biết quan điểm của bạn về các vấn đề vòng đời chuỗi cung ứng tổng thể vốn gắn liền với nền tảng quản lý gói mã nguồn mở. Những điểm cốt lõi là: quy trình xác minh để bảo đảm một formula mới trỏ đến đúng nguồn gốc có phù hợp không; người dùng làm sao chắc chắn rằng
brew updatevẫn tham chiếu đến nguồn đáng tin cậy; điều gì xảy ra nếu tên miền bị chiếm đoạt; và đội ngũ có thể phản ứng nhanh đến đâu với nguồn không đáng tin cậy của một formulaKhông phải mọi vấn đề kiểu này đều là việc Homebrew phải giải quyết, nhưng chúng là các cân nhắc quan trọng ở cấp hệ sinh thái. winget và choco cũng có cùng vấn đề, còn các kho được hỗ trợ thương mại như apt hay yum thì ít hơn. Với cá nhân tôi và nhiều quản trị viên, đây cũng là mối lo lớn khi xử lý Windows Store
Cuối cùng, nếu đội Homebrew đang xem, sẽ thật tuyệt nếu có cảnh báo lỗ hổng kiểu npm
Đã có đủ các trường hợp công khai về người liên quan đến Đảng Cộng sản Trung Quốc giành được quyền pull request trên các gói cốt lõi, và tôi nghĩ còn nhiều trường hợp không được công bố hoặc bị che đậy hơn nữa. Chỉ riêng việc quyền sở hữu gói chuyển từ một chủ thể có uy tín sang một cá nhân ít được biết đến hơn cũng đã đáng lo ngại rồi
Với tư cách một kỹ sư phần mềm/quản lý kỹ thuật chuyển sang làm VC, tôi tò mò liệu có startup hay công ty thương mại nào cung cấp các bảo đảm như vậy không. Tuy nhiên, tôi cũng lo rằng quy mô thị trường để giải quyết vấn đề này có thể không đủ lớn để trở thành một mảng kinh doanh độc lập
Trước khi chuyển sang Nix, tôi dùng MacPorts vì Homebrew khi đó hoạt động khá kỳ lạ. Nó không chạy được trong thiết lập đa người dùng, sở hữu
/usr/local, và do tự động cập nhật cùng việc thiếu quản lý phiên bản nên gây ra nhiều vấn đề kiểu “trên máy tôi thì chạy”Điều luôn khiến tôi thấy bất an ở Homebrew không phải là Git, mà là việc có thể dùng URL GitHub như một gói tạm thời. Tôi tự hỏi liệu TOB-BREW-13 có hoạt động theo cách đó không. Tính năng đó lúc nào cũng nghe như một sự cố bảo mật chỉ còn chờ xảy ra
Dù sao thì tôi cũng muốn thấy một cuộc kiểm toán Nix trên macOS. Đặc biệt tôi tò mò liệu cách
nix developvà các lệnh liên quan hoạt động có khiếm khuyết gì khôngHomebrew có thu thập analytics và các phiên bản bị hỏng quá thường xuyên. MacPorts ổn định hơn nhiều, nhưng một số gói ngách không build tốt, và có vấn đề terminfo trong tmux
Nix hay ở chỗ có thể override hầu hết những thứ này, và tôi có thể chia sẻ cấu hình home manager với workstation Debian
sandbox = truevàonix.conf, nhưng việc này có thể làm hỏng đủ thứSandbox của Nix thực ra cũng không được thiết kế như một ranh giới bảo mật. Không có nỗ lực nhằm ngăn thoát sandbox, và nhiều thứ từ host rò rỉ vào môi trường sandbox. Nếu muốn build các gói không đáng tin cậy, cần thứ gì đó như gVisor hoặc một VM hoàn chỉnh
Tôi đã lướt qua lỗi thoát sandbox và bản sửa liên quan: https://github.com/Homebrew/brew/pull/17700/commits/f4e5e0c7...
Tôi không chắc cách này có đúng không. Có vẻ họ muốn ngăn việc các ký tự được nội suy vào profile sandbox gây ra vấn đề, nhưng tôi không biết có thể tự tin đến mức nào về danh sách ký tự này
Nó không giải thích vì sao, hay các ký tự cụ thể bị cấm có gì đặc biệt. Một thông điệp tốt hơn sẽ nói kiểu như “nếu không thì ... nên chặn một số ký tự nhất định trong đường dẫn. Lý do các ký tự này cần chú ý còn các ký tự khác thì ổn là ...”
Ngay cả khi bây giờ bạn là người viết code này và biết nó làm gì, một năm sau nhìn lại bạn sẽ phải gãi đầu tự hỏi vì sao mình thực hiện thay đổi này
Có ví dụ thực tế về commit message tốt ở đây: https://github.com/git/git/commit/92fe7c7d42cc941ed70d6fce98...
Tôi đã đổi từ
brewsangnixmột thời gian trước, và text UI vẫn có thể thân thiện hơn với người dùng cuốiVì vậy tôi còn tạo một wrapper tên “ixnay” để có thể
ixnay installdễ như brew (https://github.com/pmarreck/ixnay), nhưng nhìn chung các bảo đảm mà nó mang lại là đáng giá#helptích hợp sẵnTôi đã nhắc đến ixnay trong README
Hơi ngạc nhiên là tính toàn vẹn chuỗi cung ứng — một bề mặt tấn công đòi hỏi kỹ năng thấp rất lớn của Homebrew so với gần như mọi trình quản lý gói Linux và *BSD — lại không được đề cập nhiều
Các maintainer của Homebrew nhìn chung không ký commit/gói, không ký thao tác review/merge, không xác minh chữ ký của tác giả/reviewer khi biên dịch, không tái tạo build trong CI được kiểm soát riêng, và cũng không bắt buộc xác thực hai yếu tố bằng phần cứng trên GitHub
Mức độ bảo mật của người dùng brew bị ràng buộc bởi người có an ninh vận hành kém nhất trong số hàng trăm maintainer brew vào ngày hôm đó
Ngoài ra, vì dependabot tự động tạo commit, một người có thể đưa commit độc hại vào một dự án bên ngoài do mình kiểm soát, chờ dependabot tạo commit nâng cấp trong Homebrew rồi tự merge. Trên thực tế, để trở thành maintainer Homebrew gần như không có xác minh gì và chỉ cần sửa vài lỗi dễ
Cũng có thể chiếm lấy một domain email đã hết hạn của maintainer, gửi email đặt lại mật khẩu về cho mình, rồi chiếm tài khoản của người đang đi nghỉ hoặc tạm ngưng hoạt động
Rất có khả năng họ có thể xâm phạm hàng nghìn công ty trước khi có ai đó nhận ra
Nói thật, tôi sẽ tuyệt đối không cho phép Brew trên thiết bị công ty có đặc quyền. Làm vậy chẳng khác nào trao khả năng chạy mã tùy ý trên hệ thống người dùng cho hàng trăm người ngẫu nhiên và bất kỳ ai khai thác được an ninh vận hành yếu kém của họ
Các trình quản lý gói Linux lớn cũng chưa đi đủ xa ở những phần như ký review, nhưng phần lớn ít nhất cũng có ký gói ở cấp tác giả, review bởi con người, và build tái tạo độc lập cho nhiều gói
Xét việc các mục tiêu giá trị cao như quản trị viên hệ thống công ty thường cho phép brew trên máy của họ, Brew đang trên quỹ đạo có thể vượt Crowdstrike bất cứ lúc nào về mức thiệt hại do quản lý chuỗi cung ứng thiếu sót
Nếu trên Mac có hỗ trợ PKGBUILD như Pacman với hiệu năng tương đương và các gói chương trình cốt lõi được duy trì tốt, tôi nghĩ khi dùng Mac sẽ có ít đánh đổi hơn nhiều để đổi lấy sự tiện lợi
Homebrew rất tuyệt và formula thực sự được duy trì rất tốt, nhưng vì sự đơn giản của PKGBUILD, đồng bộ nhanh, và gánh nặng nhận thức thấp hơn do không phải nhớ nhiều đối số và flag khác nhau cho từng trình quản lý gói, tôi ước gì pacman cứ chạy được trên Mac
Tôi cho rằng vector tấn công chính chỉ đơn giản là đóng góp một formula mới để lén đưa vào một gói mới độc hại
Đội ngũ maintainer quá nhỏ để audit mọi formula mới được đóng góp. Tôi ngạc nhiên là vector tấn công này không có trong cuộc audit
Ngay cả nếu đúng như vậy, đây cũng là một trong những điểm mơ hồ của việc đóng gói đã được bài viết nêu rõ. Ranh giới giữa thực thi bên thứ nhất và bên thứ ba vốn dĩ mờ nhạt; xét về giá trị bảo mật tương đối, việc tìm các điểm mà thực thi bên thứ ba có thể xảy ra ở những nơi không ngờ tới hữu ích hơn là chỉ ra mọi điều hiển nhiên sẽ xảy ra khi cố ý chạy mã bên thứ ba
Tuy vậy, tôi nghĩ toàn bộ hệ sinh thái đóng gói nên được xem xét về các quy trình phê duyệt kiểu này. Nhưng đó là vấn đề về quy trình con người, nên giống audit kiểu red team hơn là audit phần mềm
“... These avenues do not necessarily violate Homebrew’s core security assumptions (which assume trustworthy formulae),...”
Rốt cuộc thì nó vô hại, nhưng việc mọi người cứ clone những kho Git như thế rồi hy vọng mọi thứ ổn thật sự rất đáng sợ
Thấy liệt kê nhiều mục TOB-BREW-n, tôi tự hỏi liệu đó có phải kiểu số CVE riêng cho dự án này không
Sửa: À, là “Trail Of Bits - homeBREW”. Nhưng chắc ý tôi vẫn đúng
TOB-$PRODUCT-$XXXX.$PRODUCTlà đối tượng được audit và$XXXXlà bộ đếm tăng dần duy nhất cho từng phát hiệnTheo tôi biết, nhiều công ty audit cũng dùng cách tương tự
Cách diễn đạt trong bài blog này hơi gây nhầm lẫn. Bài nói rằng họ thực hiện cuộc audit này cùng Homebrew, nhưng vì cái tên nghe quen nên tôi kiểm tra README của Homebrew và thấy William Woodruff trong danh sách maintainer ở https://github.com/Homebrew/brew
Tôi tò mò liệu có lý do gì khiến điểm này không được nhắc trong bài blog không. Có lẽ không tạo ra khác biệt lớn, nhưng tôi muốn làm rõ
Tôi đã là “member” không phải maintainer của dự án trong thời gian dài; đây giống như một vị trí bán danh dự dành cho các cựu maintainer muốn tiếp tục tham gia đối thoại nội bộ và governance. Sau đó, vài tháng sau khi audit kết thúc, tôi được đề nghị trở lại làm member vì một công việc khác liên quan đến Homebrew, vốn không tồn tại và cũng không được lên kế hoạch trước khi lập kế hoạch audit
Nội dung này đã nằm trong các công bố xung đột lợi ích mà tôi gửi cho cả công ty và các maintainer Homebrew, nhưng tôi đồng ý rằng cũng có thể nêu rõ trong bài blog. Hôm nay tôi sẽ thử bổ sung
Tóm lại, vào thời điểm thực hiện audit tôi không phải maintainer, nhưng trước đây từng là maintainer và hiện nay cũng là maintainer. Cuộc audit do tôi và các đồng nghiệp thực hiện như một công việc chuyên môn