觀點 · 資訊分享

Ruby 修正正規表示式漏洞:GitLab 4 個遠端執行 CVE 的根源,有編譯使用者輸入的程式要升級

Ruby 在 10 月 23 日釋出 4.0.9、3.4.12、3.3.13,修正 GitLab 發現的正規表示式引擎記憶體錯誤。這些錯誤能讓人在 GitLab 伺服器上遠端執行程式,GitLab 已公布 4 個 CVE,最高 CVSS 10.0。

發布
2026-10-24
篇幅
約 5 分鐘 · 2,136 字
結構
7 節 + 4 題常見問題
標籤
#Ruby#GitLab#正規表示式#遠端程式碼執行#CVE-2026-110264
Ruby 修正正規表示式漏洞:GitLab 4 個遠端執行 CVE 的根源,有編譯使用者輸入的程式要升級

一句話看懂:Ruby 的正規表示式引擎有幾個記憶體錯誤,GitLab 發現能拿來在伺服器上遠端執行程式,並公布了 4 個 CVE(最高 CVSS 10.0);Ruby 在 10 月 23 日釋出 4.0.9、3.4.12、3.3.13 修正,有把使用者輸入編成正規表示式的程式要升級。

Ruby 修正正規表示式漏洞資訊圖卡:用 Regexp.new 處理使用者輸入的程式,要升到 4.0.9、3.4.12 或 3.3.13

先用白話講:正規表示式與「編譯」

正規表示式像一張「找字規則卡」,例如「以 A 開頭、後面接幾個數字」。電腦拿到規則卡之後,要先把它翻譯成內部指令才能執行,這一步叫編譯。

如果有人遞過來一張刻意寫得又長又怪的規則卡,翻譯機自己就可能出錯:讀寫到不該碰的記憶體,甚至被人趁機操控。這次的漏洞就是這種情況。

發生什麼事

GitLab 有些功能會編譯使用者提供的正規表示式,例如 CI 設定裡的比對規則。GitLab 發現,刻意設計的規則會在 Ruby 編譯時破壞記憶體,進一步能在 GitLab 伺服器上遠端執行程式。

GitLab 先在自己的版本裡修補它出貨的 Ruby,並公布 4 個 CVE;Ruby 官方則在 10 月 23 日釋出 4.0.9、3.4.12、3.3.13,把底層的錯誤修掉。

CVE 問題 GitLab 修正版
CVE-2026-89078 解析規則失敗時,同一塊記憶體被釋放兩次 19.4.1
CVE-2026-93577 編譯後規則的大小計算發生整數溢位 19.4.1
CVE-2026-97229 CI/CD 正規表示式編譯時整數溢位 19.4.2
CVE-2026-110264 規則裡重複很多次時,內部編號溢位 19.5.1

CVE-2026-110264 的 CVSS 是 10.0,GitLab 說明攻擊者不需要登入。GitLab 在 10 月 21 日發出緊急修補版本(19.5.1、19.4.3、19.3.6、19.2.9、19.1.9、19.0.10、18.11.13);GitLab.com 與 Dedicated 已修補,自架用戶要自己升級。

我的 Ruby 程式會中招嗎?

Ruby 官方說明,只有程式把攻擊者可控制的字串編成正規表示式才會碰到:

  • 使用 Regexp.new、Regexp.union、Regexp.compile
  • 把輸入塞進正規表示式字面值,例如 /#{input}/

如果正規表示式都是開發者自己寫死的,官方說不受影響。

給開發者的技術細節

Regexp.new(params[:pattern])
Regexp.union(user_words)
/#{input}/

上面這幾種寫法,處理的字串如果來自使用者,就是需要注意的地方。

  • 升級:官方建議升到 Ruby 4.0.9、3.4.12、3.3.13 或更新版本;升不了就避免編譯不可信的輸入
  • 擋不住的做法:官方明說 Regexp.timeout 不能保護這些錯誤,限制規則長度也不可靠,因為有些錯誤用很短的字串就能觸發
  • Ruby 3.3:已進入只修漏洞的維護階段,這次是例外,因為 GitLab 為相關問題指派了 CVE
  • CVE 編號:Ruby 官方目前沒有替這些修正申請 CVE,它們還在討論這類問題在文件裡該怎麼說明;追蹤時請用 GitLab 公布的 4 個編號,例如設定在弱點掃描器裡
  • 自架 GitLab:GitLab 釋出了兩個偵測規則給自架用戶,分別偵測 Onigmo 原生工作程序當機與 Org mode 渲染錯誤暴增

我的看法

「把使用者輸入的關鍵字直接丟進 Regexp.new」在 Ruby 專案裡很常見,例如搜尋框、過濾規則、後台自訂的比對條件。以前大家頂多擔心被複雜的規則拖垮效能,所以才有 Regexp.timeout 這類保護;這次是更嚴重的問題:編譯步驟本身就可能被攻破,逾時完全沒用。

我會做兩件事:第一,在專案裡搜尋 Regexp.new、Regexp.union 和 /#{,看看哪些字串其實來自使用者;第二,如果只是想「找這段文字」,通常不需要讓使用者寫規則,把輸入先用 Regexp.escape 變成純文字再編譯就夠了(這是我的建議,不是官方公告的內容)。至於自架 GitLab 的人,這類緊急修補最好當天就升,因為不需要登入就能被利用。

名詞小辭典

  • 正規表示式(Regex):用一串符號描述「要找什麼樣的文字」的規則,常用在搜尋、驗證格式。
  • Onigmo:Ruby 使用的正規表示式引擎,負責解析與執行規則。
  • 整數溢位:數字超過程式預留的空間,結果會「繞回去」變成錯誤的值,可能導致記憶體配置不足。
  • 重複釋放(Double free):同一塊記憶體被釋放兩次,會破壞程式的記憶體管理,常被拿來當成攻擊的起點。

資料來源

常見問題

正規表示式的「編譯」是什麼?
正規表示式是一種描述「怎麼找文字」的規則。程式拿到規則後,會先把它翻譯成內部的指令才能執行,這個翻譯的步驟就叫編譯。這次的漏洞就出在翻譯步驟裡,遇到刻意設計的規則會破壞記憶體。
我的 Ruby 程式有沒有受影響?
只有程式會把攻擊者可控制的字串編成正規表示式才會碰到,例如用 Regexp.new、Regexp.union、Regexp.compile,或把輸入塞進 /#{input}/。如果正規表示式都是開發者自己寫死的,Ruby 官方說不受影響。
加上逾時或限制輸入長度可以擋住嗎?
不行。Ruby 官方明確寫了 Regexp.timeout 保護不了這些錯誤,限制長度也不可靠,因為有些錯誤用很短的字串就能觸發。建議直接升級,升級不了就避免編譯不可信的輸入。
自架 GitLab 要做什麼?
GitLab 在 10 月 21 日發出緊急修補版本,自架的用戶要升級到修補版;GitLab.com 與 Dedicated 已經修補完成。GitLab 也釋出了兩個偵測規則,協助自架用戶找可能的攻擊嘗試。
LINE