本文へ移動
技術を、自社の仕事に。
判断と実行を助けるメディア

記事を検索

Ruby 4.0.9などの正規表現の修正 対象アプリの見分け方

目次 · 8項目

社内の業務システムや会員サイトがRuby on Railsで動いていて、検索画面や絞り込みの条件に「正規表現も使える」入力欄がある。そうしたアプリを持つ会社は、今回のRubyの更新を後回しにしにくい状況です。Rubyの公式の告知は、利用者が送った文字列から正規表現を作るアプリでは、作る処理の途中でメモリが壊れうると説明しています。

Rubyの開発チームは2026年10月23日、4.0.9・3.4.12・3.3.13を公開しました。告知の冒頭は次のとおりです。

We have released Ruby 4.0.9, 3.4.12 and 3.3.13. They fix several bugs in Ruby’s regular expression engine (Onigmo) that GitLab found could be used for remote code execution on GitLab servers.

公式の告知と、編集部の手元のRubyで試した版の判定の結果から、Rubyのアプリを保守する担当者が確かめることを整理します。

何が見つかったのか

きっかけはGitLabです。GitLabは、CIの設定に書かれたパターンなど、利用者が入力した正規表現を Regexp.new で組み立てています。告知によると、GitLabは細工したパターンを組み立てる途中でメモリが壊れ、それがGitLabのサーバー上での遠隔コード実行(RCE)につながることを見つけました。GitLabは自社が同梱するRubyに修正を当てて自社の版で対処し、次の4件のCVEを登録しています。

  • CVE-2026-89078:正規表現の解析での二重解放(GitLab 19.4.1で対処)
  • CVE-2026-93577:正規表現のコンパイルでの整数オーバーフロー(GitLab 19.4.1)
  • CVE-2026-97229:CI/CDの正規表現のコンパイルでの整数オーバーフロー(GitLab 19.4.2)
  • CVE-2026-110264:正規表現のコンパイルでの整数オーバーフロー(GitLab 19.5.1)

括弧内の版は、Rubyの告知が挙げた、各CVEを最初に直したGitLabの版です。GitLab自体を社内で運用している場合は、GitLabの版の確認が先です。GitLabのパッチリリースの告知によると、4件すべての修正が入っているのは、10月21日に公開された19.5.1・19.4.3・19.3.6・19.2.9・19.1.9・19.0.10・18.11.13です。たとえば19.4系では、19.4.2に上げていてもCVE-2026-110264が残ります。GitLabはCVE-2026-110264を、認証なしでGitLabのサーバー上で任意のコードを実行されうるもの(CVSS 10.0)としています。GitLabの別の脆弱性の確認手順はGitLabのCVE-2026-85706 版の確認と更新後の手順で扱っています。

影響するアプリと、しないアプリ

告知は影響の範囲をはっきり書いています。

These bugs are reached only when an application compiles a regular expression from a string that an attacker controls, for example by passing it to Regexp.new, Regexp.union or Regexp.compile, or by interpolating it into a regexp literal such as /#{input}/. Applications that only use regular expressions written by their own developers are not affected.

つまり、開発者がコードに書いた固定の正規表現(/\A\d{3}-\d{4}\z/ のようなもの)だけを使うアプリは対象外です。対象になるのは、外部から届く文字列を Regexp.new・Regexp.union・Regexp.compile に渡す、または /#{input}/ のように正規表現の中へ埋め込んでいるアプリです。

Ruby 4.0.9・3.4.12・3.3.13の修正が必要なアプリの見分け方を示した図。利用者の入力をRegexp.new・Regexp.union・Regexp.compileに渡す、または/#{input}/のように埋め込むアプリは影響を受け、開発者が書いた固定の正規表現だけのアプリは影響を受けない。Regexp.timeoutとパターンの長さの制限では防げない

告知はあわせて、次の2つの防御は今回は効かないとしています。

  • Regexp.timeout(正規表現の処理時間の上限)では防げない
  • パターンの長さを制限しても確実には防げない。短いパターンで起きる不具合もある

Regexp.timeout は、処理に時間がかかりすぎるパターン(ReDoS)への対策です。今回はパターンを組み立てる段階でメモリが壊れる問題のため、時間の上限とは別の話になります。

どの版に上げるか

告知の表を、系列ごとの修正版にまとめると次のとおりです。

系列修正版補足
4.04.0.9一部の修正は4.0.0や4.0.8で入っており、4.0.9ですべてそろう
3.43.4.12
3.33.3.13セキュリティ保守期のため本来は脆弱性の修正のみ。今回は例外として収録
3.2以前出ていないRubyの公式のページでは3.2は2026年4月1日でサポート終了

3.3.13には、2026年8月27日に公表された標準添付のgem「resolv」の脆弱性(CVE-2026-80212、CVE-2026-80213)の修正(resolv 0.3.2)も入っています。Rubyの公式のブランチの一覧によると、3.3のサポート終了は2027年3月31日の見込みです。3.3を使っている場合は、今回の更新と同時に3.4以降への移行の予定も立てておくと、来年の対応が楽になります。

告知は、すぐに上げられない場合について「信頼できない入力から正規表現を組み立てないこと」を求めています。

手元で版を判定してみた

告知の表をそのまま判定に使える小さなスクリプトを作り、編集部の検証環境(Linux、Ruby 3.3.6)で動かしました。

# 2026年10月23日のRegexpの修正が入った版かを判定する(ruby-lang.orgの告知の表に基づく)
FIXED = { "4.0" => "4.0.9", "3.4" => "3.4.12", "3.3" => "3.3.13" }
series = RUBY_VERSION.split(".")[0, 2].join(".")
need = FIXED[series]
if need.nil?
  puts "#{RUBY_VERSION}: この系列には修正版が出ていない(サポート中の系列へ移行を検討)"
elsif Gem::Version.new(RUBY_VERSION) >= Gem::Version.new(need)
  puts "#{RUBY_VERSION}: 修正済み(#{need}以上)"
else
  puts "#{RUBY_VERSION}: 要更新(#{need}以上へ)"
end

検証環境のRuby 3.3.6では「3.3.6: 要更新(3.3.13以上へ)」と表示されました。RUBY_VERSION を差し替えて境目の版も確かめ、3.3.12・3.4.11・4.0.8は「要更新」、3.3.13・3.4.12・4.0.9は「修正済み」、3.2.9は「修正版が出ていない」と判定されることを確認しています。

判定は本番と同じ環境で行います。開発者の端末、CIのイメージ、本番のサーバーやコンテナで、使っているRubyが違うことがあるためです。コンテナで動かしている場合は、土台のイメージを修正版で作り直してデプロイし直すまで古い版のままです。OSのパッケージのRubyは、修正を取り込んでも版の数字が変わらない場合があるため、パッケージの変更履歴で確かめます(今回、各ディストリビューションのパッケージの対応状況は確認していません)。変更履歴でCVEの修正を確かめる手順は、PHPの例ですがPHPに未認証RCEの脆弱性2件で示しています。

自社のコードで探すところ

上げる前でも、どのアプリが対象になりうるかは、コードから絞り込めます。次の検索は、告知が挙げた3つのメソッドと、正規表現への文字列の埋め込みを拾うものです。

grep -rnE 'Regexp\.(new|union|compile)\(|/[^/]*#\{' app lib

検証用に作った小さなRailsの形のコード(コントローラーで Regexp.new(params[:q])、モデルで /#{tag}/ を使ったもの)に対して実行し、2か所とも拾えることを確かめました。この検索はURLのパスの文字列("/users/#{id}" など)も拾うため、見つかった箇所が「外部から届く文字列か」を1つずつ確かめる必要があります。gemの中のコードは対象外のため、利用者の入力を正規表現として扱う機能を持つgemを使っている場合は、gemの側の扱いも確認します。

見つかった箇所の直し方は、機能の目的によって分かれます。ここからは編集部の提案です。

  • ただの文字列検索でよい場合:正規表現をやめ、String#include? や start_with? など、正規表現を組み立てない方法に置き換える
  • 正規表現の入力が機能として必要な場合:Rubyを修正版に上げる。あわせて、その機能を使える利用者を管理者などに絞る

Rubyの開発チームは、信頼できない入力から正規表現を組み立てる使い方をRubyがサポートするのか、どう文書に書くかをこれから議論するとしています。今回の修正を当てても、外部の文字列を正規表現にする設計は見直しの対象に残しておくのが無難です。

脆弱性スキャナーで追うときの注意

告知によると、Rubyの開発チームは今回の修正について、Rubyとしての CVE を少なくとも現時点では申請していません。脆弱性スキャナーなどで追跡するときは、GitLabが登録した4件のCVE番号を使うよう案内しています。スキャナーがRubyの版だけを見てCVEを照合する仕組みの場合、今回の4件が「Rubyの脆弱性」として表示されない可能性があります。社内の脆弱性の一覧には、版の判定の結果を手で書き足しておくと見落としを防げます。

確認した範囲

2026年10月25日に、ruby-lang.org のニュース「Regexp compilation fixes related to GitLab’s CVE-2026-89078, CVE-2026-93577, CVE-2026-97229 and CVE-2026-110264」(10月23日)、Ruby 4.0.9・3.4.12・3.3.13・4.0.8 のリリースの告知、resolv の脆弱性の告知(8月27日)の一覧での掲載、ブランチのメンテナンス状況のページを確認しました(資料調査)。2026年10月27日に、同じページと、GitLabのパッチリリースの告知(19.4.1、19.4.2、19.5.1)を確認し直しました。あわせて、編集部の検証環境(Linux、Ruby 3.3.6)で、版の判定のスクリプトと、検証用に作ったコードへのgrepの結果を確認しました(実機検証)。不具合の再現、修正版のRubyやGitLabでの動作、各OSのパッケージの対応状況、NVDの記載は確認していません。

Rubyで動く業務システムの更新や保守の体制の見直しは、開発・AI・自動化のご相談からお問い合わせください。

参考資料

この記事を共有XFacebook
鈴木 翔

技術の可能性に魅了され、学生時代からプログラミングとデジタルアートの分野に深い関心を持つ

この記事のテーマを、自社の次の一歩へ

自社での進め方を、具体的に。

つくりたい仕組み、既存システム、運用の条件を整理し、実現に向けた次の一歩を考えます。

  • 実現したい仕組み
  • 既存環境との接続
  • 運用の条件
開発・運用の構想を相談する

構想段階からご相談いただけます。この記事の情報を相談フォームに引き継ぎます。

最新記事をメールで受け取る