Ruby: 8/27発表のRubyGems脆弱性と修正方法のまとめ

こんにちは、hachi8833です。先週はRailsウォッチをお休みしてしまったことをお詫びいたします。

表題のニュースは先週のものですが、それなりに重要性が高いため改めて記事にいたしました。gemspecファイルからの入力もユーザー入力である以上サニタイズが必要なんですね。

RubyGemsで複数の脆弱性が発見・修正された(抜粋・まとめ)

参照

要点

公式ブログRubyGemsの2.6.13がリリースされました。2.6.13では、従来のRubyGems gemで見つかった複数の脆弱性が修正されています。

影響を受けるRubyバージョン

  • Ruby 2.2系のうち、2.2.7以前のバージョン
  • Ruby 2.3系のうち、2.3.4以前のバージョン
  • Ruby 2.4系のうち、2.4.1以前のバージョン
  • trunkのリビジョンが59672より前のバージョン

公式ブログ公開時点(2017/08/29)では、修正済みRubyGemsを含むRubyはリリースされていません。
その代わり、RubyGemsのバージョンを単独で2.6.13以降にアップデートすることで問題を回避できます。

修正方法

コマンドプロンプトで以下を実行することで、RubyGems gemをアップデートできます。

gem update --system

事情があってRubyGemsをアップデートできない場合、Rubyのバージョンに応じて以下のパッチを適用できます。

補足: rbenvRVMなどのバージョン管理ソフトウェアで複数のRubyを使っている場合、念のため、修正可能なすべてのバージョンで上のコマンドを実行しておくのがよいでしょう。当然ながら、VM、またはDockerやsystemd nspawnなどのコンテナでRubyを使っている場合はそちらもチェックし、必要であればアップデートします。

[Rails 5] rbenvでRubyをインストールして新規Rails開発環境を準備する

RubyGems 2.6.13の主な修正内容

DNSリクエストがハイジャックされる脆弱性の修正(CVE-2017-0902

  • DNSへの名前参照に対して中間者攻撃(MITM)が可能になっていたのを修正(8d91516fb
# lib/rubygems/remote_fetcher.rb
-      if /\.#{Regexp.quote(host)}\z/ =~ target
+      if URI("http://" + target).host.end_with?(".#{host}")
          return URI.parse "#{uri.scheme}://#{target}#{uri.path}"
        end

ANSIエスケープシーケンスの脆弱性の修正(CVE-2017-0899

  • gem spec内文字列を取り出すときに非表示文字(いわゆる印刷できない文字)を除去するようになった(ef0aa611
# lib/rubygems/text.rb
+  # Remove any non-printable characters and make the text suitable for
+  # printing.
+  def clean_text(text)
+    text.gsub(/[\u0000-\u0008\u000b-\u000c\u000e-\u001F\u007f]/, ".".freeze)
+  end

gem queryコマンドでのDOS脆弱性の修正(CVE-2017-0900

  • summaryのサイズに制限を加えた(8a38a4fc
# lib/rubygems/commands/query_command.rb
   def spec_summary entry, spec
-    entry << "\n\n" << format_text(spec.summary, 68, 4)
+    summary = truncate_text(spec.summary, "the summary for #{spec.full_name}")
+    entry << "\n\n" << format_text(summary, 68, 4)
   end

spec内のgem名に..を含めて任意のファイルを上書きできる脆弱性の修正(CVE-2017-0901

  • rubygems.orgで受け付けない無効な文字をspec名から除去するようになった(44cc27cd, ad5c0a53
# lib/rubygems/specification.rb
+  VALID_NAME_PATTERN = /\A[a-zA-Z0-9\.\-\_]+\z/ # :nodoc:

補足: Herokuでの対応について

HerokuではRuby 2.4.1についてホスト側で対応済みなので、ユーザーはローカルの環境について対応すればよいことになります。

本記事執筆時点のHerokuのドキュメントでは、GemfileでRubyバージョンを指定していない場合はデフォルトで1つ前のバージョン(現時点ではRuby 2.3.4)が使われると記載されています。アプリがデフォルトのRubyバージョンに依存しないよう、アプリのGemfileには以下のようにRubyバージョンを明示的に記載することが強く推奨されています

# Gemfile
source 'https://rubygems.org'

ruby '2.4.1'   # 👈

gem 'rails', '5.1.3'

gem 'bcrypt'
...

なお、以下のバージョンについてのChangelogはありますが、RubyGemsのバージョンは2.6.13にはなっておらず、パッチが適用済みかどうかについては確認できませんでした。

関連記事

そのパッチをRailsに当てるべきかを考える(翻訳)

Railsアプリの認証システムをセキュアにする4つの方法(翻訳)

[Rails 5] rbenvでRubyをインストールして新規Rails開発環境を準備する

【翻訳+解説】binstubをしっかり理解する: RubyGems、rbenv、bundlerの挙動

Ruby on RailsによるWEBシステム開発、Android/iPhoneアプリ開発、電子書籍配信のことならお任せください この記事を書いた人と働こう! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

hachi8833

Twitter: @hachi8833、GitHub: @hachi8833

コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。
これまでにRuby on Rails チュートリアル第2版の半分ほど、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れてそれぞれ一部を翻訳。
かと思うと、正規表現の粋を尽くした日本語エラーチェックサービス enno.jpを運営。
実は最近Go言語が好き。
仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。

hachi8833の書いた記事

週刊Railsウォッチ

インフラ

BigBinary記事より

ActiveSupport探訪シリーズ