RubyGems 導覽選單
指南

如何建立並安裝已加密簽署的寶石,以及其他安全性疑慮。

安全性實務正積極討論中。請經常回來查看。

一般

安裝寶石允許該寶石的程式碼在您的應用程式環境中執行。這顯然有安全性影響:在伺服器上安裝惡意寶石最終可能導致該伺服器遭到寶石作者的完全滲透。因此,寶石程式碼的安全性是 Ruby 社群中積極討論的主題。

自版本 0.8.11 起,RubyGems 已具備 對寶石進行加密簽署 的功能。此簽署作業使用 gem cert 指令建立金鑰對,然後將簽署資料封裝在寶石本身中。 gem install 指令可讓您選擇設定安全原則,您可以在安裝寶石前驗證其簽署金鑰。

然而,這種保護寶石的方法並未廣泛使用。它需要開發人員執行許多 手動步驟,而且寶石簽署金鑰並未建立完善的信任鏈。有關 X509 和 OpenPGP 等新簽署模型的討論正在 rubygems-trust wikiRubyGems-Developers 清單IRC 中進行。目標是改善 (或取代) 簽署系統,使其對作者而言容易執行,對使用者而言透明。

使用寶石

使用信任原則進行安裝。

  • gem install gemname -P HighSecurity:所有相依寶石都必須簽署並驗證。

  • gem install gemname -P MediumSecurity:所有已簽署的相依寶石都必須驗證。

  • bundle --trust-policy MediumSecurity:與上述相同,但 Bundler 只會辨識長 --trust-policy 標記,不會辨識短 -P 標記。

  • 注意事項:寶石憑證受到全球信賴,因此新增一個寶石的 cert.pem 會自動信賴由該憑證簽署的所有寶石。

驗證雜湊值 (若有)

gem fetch gemname -v version
ruby -rdigest/sha2 -e "puts Digest::SHA512.new.hexdigest(File.read('gemname-version.gem'))"

了解被入侵的風險,如 Benjamin Smith 的 Hacking with Gems 演講 所述

建立寶石

使用 gem cert 進行簽署

1) 建立自簽署寶石憑證

cd ~/.ssh
gem cert --build your@email.com
chmod 600 gem-p*
  • 使用您在 gemspec 中指定的電子郵件地址

2) 使用憑證設定 gemspec

將憑證公開金鑰新增至您的儲存庫

cd /path/to/your/gem
mkdir certs
cp ~/.ssh/gem-public_cert.pem certs/yourhandle.pem
git add certs/yourhandle.pem

將憑證路徑新增至您的 gemspec

s.cert_chain  = ['certs/yourhandle.pem']
s.signing_key = File.expand_path("~/.ssh/gem-private_key.pem") if $0 =~ /gem\z/

3) 將您自己的憑證新增至您的核准清單中,就像其他人一樣

gem cert --add certs/yourhandle.pem

4) 建立 gem 並測試是否可以安裝

gem build gemname.gemspec
gem install gemname-version.gem -P HighSecurity
# or -P MediumSecurity if your gem depends on unsigned gems

5) 安裝文件範例文字

MetricFu 已加密簽署。要確保您安裝的 gem 未被竄改

將我的公開金鑰 (如果您尚未執行此操作) 新增為受信任憑證

gem cert --add <(curl -Ls https://raw.github.com/metricfu/metric_fu/master/certs/bf4.pem)

gem install metric_fu -P MediumSecurity

MediumSecurity 信任設定檔會驗證已簽署的 gem,但允許安裝未簽署的依賴項。

這是必要的,因為並非 MetricFu 的所有依賴項都已簽署,因此我們無法使用 HighSecurity。


在您的儲存庫中包含已發布 gem 的檢查碼

require 'digest/sha2'
built_gem_path = 'pkg/gemname-version.gem'
checksum = Digest::SHA512.new.hexdigest(File.read(built_gem_path))
checksum_path = 'checksum/gemname-version.gem.sha512'
File.open(checksum_path, 'w' ) {|f| f.write(checksum) }
# add and commit 'checksum_path'

有關詳細資訊,請參閱與 Yorick Peterse 的討論

報告安全性漏洞

報告他人的 gem 的安全性漏洞

如果您發現他人的 gem 中有安全性漏洞,則您的第一步應該是檢查這是否已知的漏洞。一種方法是在 RubySec 上搜尋建議。

如果這看起來像新發現的漏洞,則您應該私下聯絡作者 (即,不透過公開專案的 pull request 或問題) 說明問題、如何利用它,並理想情況下提供如何修復它的指示。

報告您自己的 gem 的安全性漏洞

首先,透過電子郵件 聯繫這些地方之一或透過建立 安全性建議在 GitHub 上要求 CVE 識別碼。在討論時,此識別碼將有助於唯一識別漏洞。

其次,找出依賴您的 gem 的人應該採取什麼措施來解決漏洞。這可能涉及發布您建議他們升級的已修補版本的 gem。

最後,您需要告訴大家這個漏洞。目前沒有單一的地方可以廣播此資訊,但一些不錯的起點可能是

  • 發送電子郵件到多個清單,包括 ruby-security-ann@googlegroups.com、rubysec-announce@googlegroups.com 和 oss-security@lists.openwall.com,概述漏洞、它影響的 gem 版本,以及依賴該 gem 的人應該採取的措施。請務必使用包含 gem 名稱、漏洞簡短摘要和 (如果您有) CVE ID 的主旨。

  • 將其新增到 ruby-advisory-db。您可以透過遵循 CONTRIBUTING 指南並提交 pull request 來執行此操作。

鳴謝

本指南的內容使用了多個來源