1 điểm bởi GN⁺ 2024-07-31 | 1 bình luận | Chia sẻ qua WhatsApp
  • 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 brew dẫ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 token sudo, và cài formula từ URL không cục bộ
  • Trong CI/CD, trigger pull_request_target và đầu vào workflow_dispatch khô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 brew và 3 kho lưu trữ lân cận quan trọng về bảo mật
  • 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 brew và 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 install rõ 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 foo có 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 install có 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ản curl đ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_dispatch khô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
  • Ngoài các vấn đề riêng của CI/CD, một số phát hiện liên quan tới brew cũ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

 
GN⁺ 2024-07-31
Ý 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 update vẫ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 formula
    Khô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

    • Vấn đề này đặc biệt nghiêm trọng khi trình quản lý gói được dùng trong môi trường vận hành hoặc pipeline CI/CD
      Đã 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 develop và các lệnh liên quan hoạt động có khiếm khuyết gì không

    • Thú vị là tôi cũng chuyển theo thứ tự Homebrew -> MacPorts -> Nix
      Homebrew 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
    • Trên macOS, Nix mặc định không dùng sandbox build. Có thể tự bật bằng cách thêm sandbox = true vào nix.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
    • Nix cũng cho phép github
  • 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

    • Commit message lẽ ra đã có thể trả lời câu hỏi đó, nhưng thực tế chỉ lặp lại điều diff đã cho thấy: “không cho phép ký tự đặc biệt trong đường dẫn quy tắc sandbox”
      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...
    • Nếu đó là bản sửa thì tôi cũng ngạc nhiên. Danh sách cho phép không tốt hơn blacklist sao?
  • Tôi đã đổi từ brew sang nix mộ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ối
    Vì vậy tôi còn tạo một wrapper tên “ixnay” để có thể ixnay install dễ 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á

    • Tôi cũng thấy dòng lệnh của nix phiền phức. Phải thử cái này xem. Tôi thích tài liệu #help tích hợp sẵn
    • Giá mà tôi biết ixnay sớm hơn. Tôi cũng bực mình với trải nghiệm người dùng nên cuối cùng tự tạo công cụ riêng, tên là hdn: https://github.com/seasonedfish/hdn
      Tô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

    • pacman mặc định không hoạt động trên macOS như kỳ vọng, nhưng có những nỗ lực chỉnh sửa/hack một chút để làm cho nó chạy được: https://github.com/liudongmiao/pacman, https://github.com/kladd/pacman-osx
    • Đã từng có vài nỗ lực như vậy. Một số trong đó có thể thực sự đang hoạt động
    • MacPorts chẳng phải cũng giống vậy sao? Tôi hỏi thật vì tò mò
  • 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

    • Tôi không nghĩ các reviewer formula core hiện tại của Homebrew sẽ cho rằng đội của họ quá nhỏ để xem xét đầy đủ các yêu cầu formula mới gửi vào
      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
    • Phần đó đã được ghi lại, và họ giả định rằng formula là đáng tin cậy
      “... These avenues do not necessarily violate Homebrew’s core security assumptions (which assume trustworthy formulae),...”
    • Vài ngày trước tôi cũng giật mình khi thấy ai đó tải một trình giả lập console tên “Cmder”. Nó là một tập hợp nhiều công cụ FOSS, và có đúng nghĩa khoảng 1.000 tệp có thể độc hại như script PowerShell, script Perl, script Python, shell script, DLL, EXE, v.v.
      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

    • Đúng vậy. Với kết quả audit, chúng tôi dùng quy ước TOB-$PRODUCT-$XXXX. $PRODUCT là đối tượng được audit và $XXXX là bộ đếm tăng dần duy nhất cho từng phát hiện
      Theo 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õ

    • Vào thời điểm thực hiện audit thì tôi chưa phải maintainer :-)
      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