テック技報最新号へ →
セキュリティ

利用者が書いた文字列を Ruby の正規表現としてコンパイルしない(Onigmo のメモリー破壊と GitLab の RCE)

Ruby の正規表現エンジン Onigmo に、パターンをコンパイルする段階でメモリーが壊れる不具合が見つかり、GitLab では RCE(リモートコード実行)4 件につながった。攻撃者が渡した文字列を正規表現にするアプリだけが対象で、更新できるまでは「信頼できない入力をコンパイルしない」ことが唯一の確実な回避策。

@MalwareBibleJP · 2026-10-28
#ruby#regexp#rce#input-validation#patch-management

影響を受けるコード

問題はマッチ時ではなくコンパイル時に起きるため、入力をパターンとして受け取った時点で危ない。次のような書き方が対象になる。

ruby
Regexp.new(params[:pattern])          # 利用者入力をそのままパターンに
Regexp.union(user_supplied_list)      # 利用者が並べた文字列の union
Regexp.compile(config["only_match"])  # 設定ファイル由来(CI 設定など)
/#{user_input}/                       # リテラルへの埋め込みも同じ

開発者が自分で書いた固定のパターンだけを使うアプリは対象外。GitLab は利用者が書いた CI 設定のパターンを Regexp.new でコンパイルしていたため影響を受けた。

対策

  1. Ruby を更新する。 4.0.9 / 3.4.12 / 3.3.13 以降。4.0 系は段階的に修正が入ったので、4.0.8 では足りない。Docker イメージやアプリ同梱の Ruby(GitLab のように独自にバンドルしているもの)も忘れずに確認する。
  2. 更新までは信頼できない入力をコンパイルしない。 部分一致で足りるなら Regexp.escape(input) で文字列として扱うか、String#include? や start_with? に置き換える。どうしてもパターンを受け付ける機能(検索、ルール設定など)は一時的に止めるか、管理者だけに絞る。
  3. Regexp.timeout や長さ制限に頼らない。 今回の不具合は ReDoS(処理時間の爆発)ではないので timeout では防げず、短いパターンでも起きるため長さ制限も確実ではない。
  4. CVE で追跡する場合は GitLab 側の番号を使う。 Ruby 本体としての CVE は現時点で未申請で、GitLab の CVE-2026-89078 / 93577 / 97229 / 110264 が案内されている。脆弱性スキャナーが Ruby の版で拾わない可能性があるので、手元で版を確認する。

洗い出しのコツ

  • rg -n 'Regexp\.(new|union|compile)|/#\{' app lib で動的なパターン生成箇所を探し、引数がリクエスト・DB・設定ファイルのどこから来るかを追う。
  • 「利用者がフィルターやルールを書ける」機能(通知ルール、ブランチ保護、ログ検索など)は特に注意。

出典

X の元の投稿を開く