利用者が書いた文字列を Ruby の正規表現としてコンパイルしない(Onigmo のメモリー破壊と GitLab の RCE)
Ruby の正規表現エンジン Onigmo に、パターンをコンパイルする段階でメモリーが壊れる不具合が見つかり、GitLab では RCE(リモートコード実行)4 件につながった。攻撃者が渡した文字列を正規表現にするアプリだけが対象で、更新できるまでは「信頼できない入力をコンパイルしない」ことが唯一の確実な回避策。
影響を受けるコード
問題はマッチ時ではなくコンパイル時に起きるため、入力をパターンとして受け取った時点で危ない。次のような書き方が対象になる。
ruby
Regexp.new(params[:pattern]) # 利用者入力をそのままパターンに
Regexp.union(user_supplied_list) # 利用者が並べた文字列の union
Regexp.compile(config["only_match"]) # 設定ファイル由来(CI 設定など)
/#{user_input}/ # リテラルへの埋め込みも同じ開発者が自分で書いた固定のパターンだけを使うアプリは対象外。GitLab は利用者が書いた CI 設定のパターンを Regexp.new でコンパイルしていたため影響を受けた。
対策
- Ruby を更新する。 4.0.9 / 3.4.12 / 3.3.13 以降。4.0 系は段階的に修正が入ったので、4.0.8 では足りない。Docker イメージやアプリ同梱の Ruby(GitLab のように独自にバンドルしているもの)も忘れずに確認する。
- 更新までは信頼できない入力をコンパイルしない。 部分一致で足りるなら
Regexp.escape(input)で文字列として扱うか、String#include?やstart_with?に置き換える。どうしてもパターンを受け付ける機能(検索、ルール設定など)は一時的に止めるか、管理者だけに絞る。 Regexp.timeoutや長さ制限に頼らない。 今回の不具合は ReDoS(処理時間の爆発)ではないので timeout では防げず、短いパターンでも起きるため長さ制限も確実ではない。- CVE で追跡する場合は GitLab 側の番号を使う。 Ruby 本体としての CVE は現時点で未申請で、GitLab の CVE-2026-89078 / 93577 / 97229 / 110264 が案内されている。脆弱性スキャナーが Ruby の版で拾わない可能性があるので、手元で版を確認する。
洗い出しのコツ
rg -n 'Regexp\.(new|union|compile)|/#\{' app libで動的なパターン生成箇所を探し、引数がリクエスト・DB・設定ファイルのどこから来るかを追う。- 「利用者がフィルターやルールを書ける」機能(通知ルール、ブランチ保護、ログ検索など)は特に注意。
出典
- @MalwareBibleJP · 2026-10-27
- 一次情報: Ruby 公式 ruby-lang.org