· 約 7 分鐘閱讀 · 資安與維運 · Read in English
GitLab 五週四輪修補:正規表示式 RCE 進 KEV,自架團隊和 Ruby 專案該做的事
9/23 到 10/29,GitLab 為同一類 Ruby 正規表示式引擎(Onigmo)漏洞連發三輪修補,再加一輪 eMudhra 憑證撤銷;其中 CVE-2026-97229 在 10/29 被 CISA 列入已遭利用清單。Ruby 也在 10/23 發布修補版。整理時間線、官方還沒說的部分,以及自架 GitLab 與 Ruby 專案這週該檢查的事。
GitLab 五週四輪修補:正規表示式 RCE 進 KEV
10 月 29 日,美國 CISA 把 GitLab 的 CVE-2026-97229 加入已遭利用漏洞清單(KEV)。這是一個 CVSS 10.0 的漏洞:不需要登入,只要送出特製的正規表示式,就可能在 GitLab 伺服器上執行任意程式碼。
麻煩的地方不只這一個。從 9 月 23 日到 10 月 29 日,GitLab 發了四輪安全修補,其中三輪都跟同一個根源有關:Ruby 內建的正規表示式引擎 Onigmo 在編譯特製 pattern 時會破壞記憶體。Ruby 官方也在 10 月 23 日發布了修補版。台灣很多公司和接案團隊是自架 GitLab,版本常常停在「上次有人有空升級的那天」。這篇整理時間線,以及這週該確認的事。
一、發生什麼事
以下日期、版本與 CVSS 都以 GitLab 官方發布說明、Ruby 官方公告、CISA KEV 資料與 NVD 為準。
9/23:GitLab 19.4.1、19.3.3、19.2.7
- 發布說明修了兩個 Critical(CVSS 9.9):CVE-2026-89078(正規表示式解析器 double free)與 CVE-2026-93577(正規表示式編譯器整數溢位)。
- 兩個都要已登入的使用者在 CI/CD 設定裡放特製正規表示式才能觸發。受影響的是 19.2 到 19.4 版本線。
10/12:GitLab 19.4.2、19.3.5、19.2.8
- 發布說明的第一項就是 CVE-2026-97229:CI/CD 正規表示式編譯器整數溢位,CVSS 10.0,向量是
PR:N,也就是不需要登入。受影響的是 19.2.8、19.3.5、19.4.2 之前的 19.2 到 19.4。 - 這一輪一共修了 24 個 CVE,另外還有 5 個 High,例如語法高亮 XSS(8.7)、Developer 角色可以在受保護分支跑 pipeline(8.5)。
- GitLab 同時提供了 6 條給自架環境用的偵測規則,名稱包括「Onigmo native worker crash」等,用來從日誌找利用嘗試。
10/21:GitLab 19.5.1,並回補到 18.11.13
- 發布說明修了 CVE-2026-110264:同樣是正規表示式編譯時的整數溢位,CVSS 10.0、不需要登入。差別是範圍:從 7.0 開始的所有版本都受影響,所以這次一路回補到 19.5.1、19.4.3、19.3.6、19.2.9、19.1.9、19.0.10、18.11.13。
- 發布說明特別寫:如果你不是用官方 Linux 套件或容器映像,而是自己提供 Ruby 執行環境,Ruby 也要一起升到 3.3.13、3.4.12、4.0.9 或更新,因為修補在 Ruby 裡。
- 同一輪還有兩個 High:CVE-2026-15723(同時開 OmniAuth SAML 與 LDAP 自動連結時,可能接管既有 LDAP 帳號,8.2)與 CVE-2026-112212(OAuth/OIDC discovery 端點快取汙染,7.5)。
10/23:Ruby 4.0.9、3.4.12、3.3.13
- Ruby 官方公告說明,這幾個版本修了上面四個 GitLab CVE 背後的 Onigmo 問題。Ruby 3.3 本來只收安全修補,這次是破例納入。
- 影響範圍:只有會把「攻擊者控制的字串」編譯成正規表示式的程式,例如
Regexp.new、Regexp.union、Regexp.compile,或把輸入插進/#{input}/。只用開發者自己寫死的正規表示式,不受影響。 - 兩個常見的「自以為有防到」:
Regexp.timeout擋不住;限制 pattern 長度也不可靠,有些問題用很短的 pattern 就能觸發。 - Ruby 目前還沒有為這些修補申請自己的 CVE 編號,公告說先用 GitLab 的 CVE 追蹤。
10/29:CISA KEV 與 GitLab 19.5.3 同一天
- KEV 加入 CVE-2026-97229,聯邦機關期限是 11/1,而且標示需要鑑識分級(forensic triage)。KEV 的備註寫到:其他產品也可能受同一個 Ruby/Onigmo 問題影響。
- 同一天 GitLab 發布 19.5.3 等版本,從內建的憑證庫移除 8 張遭外洩的 eMudhra 中繼 CA(CVE-2026-111943)。這件事的來龍去脈我寫在 eMudhra 中繼 CA 私鑰外洩。要注意:GitLab Runner 和 AI Gateway 要另外升級,自己打包
ca-certificates的 CI 映像也要重建。
二、官方沒說、或還沒定案的部分
- CVE-2026-97229 是誰在打、打了多少台,CISA 和 GitLab 都沒有公布。GitLab 10/29 的發布說明也沒有提到利用狀況。
- CVE-2026-110264 目前不在 KEV 裡(以我查到的 11/6 版 KEV 資料為準),新加坡 CSA 的警示也沒說已被利用。但它的影響範圍比 97229 大很多,而且同樣不需要登入。「還沒進 KEV」不等於「沒人在打」。
- 具體的攻擊路徑還沒公開。 GitLab 的慣例是修補 90 天後才公開議題細節。19.5.1 的偵測規則裡有一條叫「Org mode render error burst」,部分二手報導據此說觸發點在
.org檔案渲染,但官方 CVE 描述沒有這樣寫,我沒有辦法核對。 - 為什麼跳過 19.5.2 和 19.4.4,官方只說這兩個版本號不存在,沒有說明原因。
- Ruby 沒有 CVE 編號的副作用(推論):很多弱點掃描工具是靠 CVE 比對版本。在 Ruby 申請 CVE 之前,自己編譯 Ruby 的環境可能不會被掃描器標出來,要靠人工確認版本。
三、我怎麼看
第一,同一個根源,一個月修了三次。 9/23 修的是「要登入」的版本,10/12 變成「不用登入」,10/21 擴大到「從 7.0 開始全部」。這很像典型的發展:研究者找到一個脆弱的元件之後,會沿著它繼續找其他入口。所以「我 9 月底升過了」在這次完全不算數。
第二,CI/CD 設定本身就是輸入。 我們習慣把 .gitlab-ci.yml 當作「自己人寫的設定檔」,但 GitLab 會解析它、編譯裡面的正規表示式,而解析的程式就跑在伺服器上。任何讓使用者(甚至匿名使用者)把字串送進正規表示式引擎的地方,都是攻擊面。
第三,這不只是 GitLab 的事。 Ruby 公告說得很清楚:只要你的 Ruby 程式把使用者輸入丟進 Regexp.new,就屬於同一類風險。站內搜尋、後台的自訂過濾規則、讓使用者輸入「進階比對條件」的功能,都值得回頭看一下。
第四,KEV 標了「需要鑑識分級」。 跟上週整理的 SSL VPN 那一波一樣,這代表 CISA 認為:升級之前如果已經被打過,升級完也不等於沒事。GitLab 伺服器通常放著原始碼、CI 變數、部署金鑰和各種 token,被拿到 root 的代價很高。
四、實務建議
自架 GitLab 的公司(IT 負責人、DevOps)
- 先確認版本。 Omnibus 安裝可以用
sudo gitlab-rake gitlab:env:info看 GitLab 與 Ruby 版本;Docker 安裝則在容器裡執行同一個指令。(指令依官方文件慣例列出,未在本文環境實測。) - 目標是 10/29 那一輪的版本:19.5.3、19.4.5、19.3.7、19.2.10、19.1.10、19.0.11 或 18.11.14。它同時包含兩個 10.0 漏洞與 eMudhra 憑證的修補。如果版本比 18.11 還舊,就不在回補範圍內,要規劃升級路徑。
- 單機安裝要排停機。 這幾輪都有資料庫 migration,官方說單節點升級會有停機,多節點可以用零停機程序。
- 19.2 到 19.4 在 10/12 前曾對外開放的機器,要當成可能已被入侵處理。 用 GitLab 提供的偵測規則掃日誌;有疑慮就輪換 CI/CD 變數、部署金鑰、Runner 註冊 token 與個人存取權杖。
- 別忘了 Runner 和 CI 映像。 依 19.5.3 的說明,GitLab 本體升級不會更新 Runner,自己打包
ca-certificates的 CI 映像也要重建。 - 同時開了 SAML 與 LDAP 自動連結的, 確認已經在 19.5.1 那一輪之後(CVE-2026-15723)。
用 Ruby 寫服務的團隊
- 把 Ruby 升到 4.0.9、3.4.12、3.3.13 或更新。用 Docker 的話,確認基底映像真的換到新版,不只是重 build。
- 盤點程式碼裡把外部輸入編進正規表示式的地方,例如搜尋
Regexp.new、Regexp.union、Regexp.compile和/#{。能改成固定 pattern 或Regexp.escape的就改。 - 不要把
Regexp.timeout或長度限制當作這次的防護。
代管客戶 GitLab 的接案團隊、外包 MIS
- 把客戶的 GitLab 版本列進資產清單。這五週就有四次要動的理由,沒有清單的話很難說清楚哪台升了、哪台還沒。
- 如果你幫客戶管的是 GitLab.com 或 GitLab Dedicated,官方說都已修補,不需要動作;但自架的 Runner 仍然是你的責任。
工程主管
- 檢查 GitLab 是否直接開在網際網路上。如果只有內部人員在用,放到 VPN 或零信任存取後面,可以大幅降低「不用登入」這類漏洞的風險。
- 把「CI 平台」列進和 VPN 同一級的關鍵資產。它握有的權限,往往比任何一台應用伺服器都大。
五、對這個站的影響
8plus 的原始碼放在 GitHub,部署在 Cloudflare Workers,專案本身是 Next.js 16.4.5 + pnpm,沒有 Ruby 依賴,也沒有自架 GitLab,所以這幾個漏洞不直接影響這個站。
可以借鏡的是「CI 設定也是輸入」這件事。這個站目前沒有在 repo 裡設定 GitHub Actions workflow,但未來如果加上,任何會把 PR 標題、分支名稱這類外部字串帶進腳本的步驟,都應該用同樣的眼光檢查。這是檢查方向,不是已完成的稽核結果。
GitLab 這五週的教訓很直接:同一個元件出事,往往不會只修一次,而「上次升過級」不等於「現在是安全版本」。如果你想盤點公司的 CI/CD 平台與對外服務,或把修補節奏寫進維運流程,可以預約 30 分鐘初談。