GitLabの脆弱性CVE-2026-110264(CVSS 10.0)とは?セルフホストのGitLabを守るアップデート手順と確認ポイント

GitLabの脆弱性CVE-2026-110264(CVSS 10.0)とは?セルフホストのGitLabを守るアップデート手順と確認ポイント

2026年10月21日、ソースコードの保管庫と開発作業をまとめて管理するソフト「GitLab(ギットラボ)」が、深刻度の点数で満点の10.0とされる欠陥CVE-2026-110264を含む、12件の脆弱性を直す修正版を公開しました。同じ日にはPHPの重大な欠陥「PHP2Shell」の修正版も出ており、ニュースの扱いはそちらに比べると小さめでした。ただ、自分のサーバーでGitLabを動かしている人にとっては、こちらのほうが直接の関係があるかもしれません。

この欠陥は、ログインしていない第三者が、条件がそろえばGitLabのサーバーの上で好きなプログラムを動かせてしまうというものです。しかも、影響を受けるのは2014年に出たGitLab 7.0以降のほぼすべての版で、10月12日に出たばかりの別の修正を当てたサーバーも対象に含まれます。GitLabの公式発表では、使える回避策は示されておらず、修正版に上げることが唯一の対処とされています。

関連記事の「”Black October”の10日間」では、この件を一覧表の1行で紹介しました。この記事では、GitLabの公式のパッチリリース記事を中心に、欠陥の中身、同時に直された11件の脆弱性、10月12日と9月に出た別の満点の欠陥とのつながりを整理します。

そのうえで、自宅や社内でGitLabを動かしている人が実際に手を動かせるように、バージョンの確かめ方、バックアップ、アップグレードの道筋(必須の中継バージョン)、データベースの移行、攻撃されていないかの確認、Runnerのトークンの入れ替え、外部公開の見直しまでを、順を追って説明します。

この記事の要点

先に結論を書いておくと、次の5つです。

  • CVE-2026-110264は、GitLabが正規表現(文字の並びのパターン)を組み立てる処理の整数オーバーフローで、認証なしで遠隔からコードを実行されうる欠陥です。CVSSは10.0で、GitLab 7.0以降が対象です。GitLab.comは修正済みで、自分でGitLabを動かしている場合(セルフマネージド)だけ対応が必要です。
  • 修正版は19.5.1、19.4.3、19.3.6、19.2.9、19.1.9、19.0.10、18.11.13です。10月12日の修正版(19.4.2、19.3.5、19.2.8)では直っていません。18.10以前の系列には修正版が出ていないので、18.11.13以上まで上げる必要があります。
  • 同時に直された残り11件(Highが2件、Mediumが5件、Lowが4件)は、19.5.1、19.4.3、19.3.6でしか直っていません。18.11〜19.2の系列の修正版は、満点の1件だけを直したものです。
  • 10月24日の時点で、GitLabは悪用を報告しておらず、CISAの悪用確認済みの一覧(KEV)にも入っていません。GitHubには「クラッシュを起こすところまで」と説明する検証用のコードが公開されていますが、侵入までを示した公開のコードは確認されていません。
  • やることの順番は、バージョンの確認、バックアップ(設定ファイルを含む)、アップグレードパスの確認、修正版への更新、バックグラウンドの移行の完了確認、検知ルールでのログ確認、必要ならトークンと秘密情報の入れ替え、です。

10月21日のCritical Patch Releaseで何が出たのか

小さなサーバー室に並ぶラックサーバーと配線

まず、GitLabがどんな形で修正を出したのかを確かめておきます。GitLabは、毎月の機能追加の版とは別に、不具合やセキュリティの修正だけをまとめた「パッチリリース」を定期的に出しています。

中でも特に急いで当ててほしいものは「Critical Patch Release(緊急のパッチリリース)」という名前で公開されます。10月21日の公開はこの緊急版で、公式の記事は「影響を受ける版を使っているすべてのセルフマネージドのGitLabを、ただちにこれらの版に上げることを強く勧める」という趣旨で始まっています。

ここで、GitLabの使い方の種類を整理しておきます。GitLabには、大きく分けて3つの使い方があります。GitLab社が運営するクラウドの「GitLab.com」、GitLab社が顧客ごとに専用の環境を用意して運用する「GitLab Dedicated」、そして利用者が自分のサーバーにGitLabを入れて動かす「セルフマネージド」です。

図:GitLabの3つの使い方と、今回の対応
GitLab.com
  • GitLab社が運営するクラウド
  • 修正済みで、対応は不要
GitLab Dedicated
  • 顧客ごとの専用の環境
  • 19.3.5-internal0または19.4.2-internal0以降なら修正済み
セルフマネージド
  • 自分のサーバーで動かす
  • この記事の手順が必要

この記事でいう「セルフホストのGitLab」は、3つ目のセルフマネージドのことです。社内のサーバーやクラウドの仮想マシン、自宅のNASやミニPCの上でGitLabを動かしている場合が、これに当たります。

公式の記事によると、GitLab.comはすでに修正済みの版で動いています。GitLab Dedicatedは、19.3.5-internal0または19.4.2-internal0以降で動いている環境には修正がすでに入っており、利用者の対応は不要とされています。つまり、手を動かす必要があるのはセルフマネージドの利用者だけです。GitLab.comの上でプロジェクトを管理しているだけの方は、この記事の手順を実行する必要はありません。

公開された版と、それぞれの位置づけは次のとおりです。

系列修正版直った内容
19.519.5.1CVE-2026-110264を含む12件すべて
19.419.4.312件すべて(データベースの移行あり)
19.319.3.612件すべて(データベースの移行あり)
19.219.2.9CVE-2026-110264のみ(さかのぼって修正)
19.119.1.9CVE-2026-110264のみ(さかのぼって修正)
19.019.0.10CVE-2026-110264のみ(さかのぼって修正)
18.1118.11.13CVE-2026-110264のみ(さかのぼって修正)

GitLabは、ふだんは最新の3つの系列(今回なら19.5、19.4、19.3)にだけセキュリティの修正を出します。今回は欠陥の重さを考えて、19.2から18.11までの4つの系列にも、満点の1件だけをさかのぼって直した版を用意しました。こうした「古い系列への修正の持ち込み」はバックポートと呼ばれます。

逆にいうと、18.10以前の系列には修正版がありません。18.10以前の版を使っている場合は、後の節で説明する「アップグレードパス」に沿って、少なくとも18.11.13まで上げる必要があります。

また、表の右の列にあるとおり、19.2.9から18.11.13までの4つの版は、満点の1件しか直していません。同じ日に直されたほかの11件は、19.3.6、19.4.3、19.5.1でしか直っていないので、バックポートの版に上げただけでは、その11件は残ったままになります。とりあえず満点の欠陥をふさぐためにバックポートの版を当て、そのあと時間をかけて新しい系列に移る、という二段構えで考えるのが現実的です。

公式の記事には、セキュリティ以外の不具合の修正も各版に並んでいます。たとえば次のようなものです。

  • 19.5.1:前段で通信を受け持つ「Workhorse」が、Gitのデータを扱うサーバー「Gitaly」の混雑を示す応答を受けたときに429(混み合っている)を返すようにする修正。文書を表示用に変換する部品gitlab-markupを2.2.0に、Rubyの文書変換の部品rdocを8.1.0に更新する変更
  • 19.1.9:PostgreSQL 17.11への更新
  • 18.11.13:同梱のチャットツールMattermostのセキュリティ更新や、アップロードの時間切れを35分から60分に延ばす変更

後で触れますが、gitlab-markupの更新と、Rubyの正規表現の処理に当てる修正は、今回の満点の欠陥と関係が深いとみられます。

CVE-2026-110264の中身:正規表現を組み立てる処理の整数オーバーフロー

木の机に置いたノートとコーヒー

次に、満点とされた欠陥の中身を見ていきます。GitLabの公式記事の説明は短く、要点は「条件がそろうと、認証されていない利用者が、細工した正規表現をコンパイルさせることで、GitLabのサーバー上で任意のコードを実行できた」というものです。欠陥の名前は「正規表現のコンパイラーにおける整数オーバーフロー」で、報告者はjoaxcar氏、報告の経路はHackerOneです。

いくつかの言葉を噛みくだいておきます。正規表現は、「数字が3けた続く」「aで始まりzで終わる」のような文字の並びのパターンを、記号を組み合わせて書く書き方です。検索や入力のチェック、ファイル名の振り分けなど、あらゆるソフトの中で使われています。

プログラムが正規表現を使うときは、まず書かれたパターンを読み取り、照合のための内部の手順に組み立て直します。この組み立ての作業を「コンパイル」と呼びます。

整数オーバーフローは、数を入れておく入れ物の大きさを超える値を入れようとしたときに、数があふれて、まったく違う値(たとえば大きな正の数がマイナスの数)になってしまう現象です。プログラムは、あふれた後の誤った値を正しいものと思い込んで処理を続けるため、本来は確保していないメモリーの場所に書き込んでしまうことがあります。これが、外から好きなプログラムを動かされる入口になります。

ポイント

HackerOneは、企業が外部の研究者から欠陥の報告を受け付け、内容に応じて報奨金を払う仕組みを提供している大手のサービスです。GitLabはここで報告を受け付けており、今回の12件のうち多くもHackerOne経由で報告されています。

深刻度10.0の内訳

CVSS(共通脆弱性評価システム)は、脆弱性の深刻さを0から10の点数で表す世界共通の物差しです。公式の記事に載っているCVE-2026-110264の評価の内訳は「AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H」です。これを日本語に直すと、次のようになります。

項目値意味
攻撃の経路(AV)Nネットワーク越しに攻撃できる
攻撃の難しさ(AC)L特別な条件がなく、難しくない
必要な権限(PR)Nログインや権限はいらない
利用者の操作(UI)N誰かにクリックさせるなどの操作はいらない
影響の範囲(S)C欠陥のある部品の外側にまで影響が広がる
機密性・完全性・可用性(C/I/A)H/H/H情報が読まれ、書き換えられ、止められる。いずれも影響が大きい

すべての項目が攻撃する側にとって有利な値になっているので、点数は満点の10.0です。ただし、公式の説明には「条件がそろうと」という一文が入っています。

どんな条件なのかは公式の記事では明かされておらず、GitLabは通常、修正からおよそ30日後に報告の中身を公開する方針をとっています(解説記事の中には90日後とするものもあります)。細部が分かるまでは、「自分のGitLabにはその条件が当てはまらないはずだ」と決めつけないほうが安全です。

原因はRubyの正規表現エンジン「Onigmo」とみられる

GitLabの本体は、主にRuby(ルビー)というプログラミング言語で書かれています。Rubyで正規表現を扱うときに中で働いているのが、「Onigmo(オニグモ)」という正規表現エンジンです。

エンジンは、パターンを組み立てて照合する心臓部のプログラムのことで、OnigmoはC言語で書かれ、Ruby本体に組み込まれています。日本で生まれた「鬼車(Oniguruma)」という正規表現エンジンを元にしたもので、Rubyを使うあらゆるソフトがこのエンジンのお世話になっています。

公式の記事の不具合修正の一覧には、次のような項目があります。

  • 19.2.9以降の各版:「Rubyの正規表現の繰り返しIDのオーバーフローに対する修正を、Ruby 3.3、3.4、4.0向けに追加」
  • 19.1.9、19.0.10、18.11.13:「Rubyの正規表現の範囲付き繰り返しの二重解放に対する修正を、Ruby 3.3と3.4向けに追加」という、名前の違う項目

GitLabが公開した検知ルールの名前も「Onigmo native worker crash(Onigmoのネイティブなワーカーのクラッシュ)」です。こうした点から、今回の欠陥はGitLab自身のRubyのコードというより、GitLabが同梱しているRubyの正規表現エンジンの側にあり、GitLabはそれを自分の配布物の中で直した、と読むのが自然です。

ここで大切なのは、GitLabの公式のパッケージ(Linux用のパッケージやDockerのイメージ)を使っている場合は、Rubyも一緒に修正済みのものに入れ替わる点です。一方で、GitLabをソースコードから自分で組み立て、Rubyも自分で用意している場合は、GitLabを上げただけではRubyの側が古いままになるおそれがあると指摘する解説記事があります。

ソースからの導入は少数派ですが、該当する方は、自分の環境のRubyがどう用意されているかを確かめてください。なお、10月24日の時点で、Ruby公式のサイトでこの件の独立したセキュリティ情報は確認できませんでした。

入口は「Org-mode」の文書ファイルとする解説

公式の記事は、攻撃者がどの機能を通って正規表現のエンジンにたどり着くのかを明かしていません。ただ、GitLabが公開した2つ目の検知ルールの名前は「Org mode render error burst(Org-modeの表示エラーの急増)」です。複数の解説記事は、GitLabのこの検知ルールの説明をもとに、次のような仕組みを紹介しています。

  • GitLabは、リポジトリの中にある「.org」という拡張子のファイル(Org-modeという書式で書かれた文書)を、Webの画面で読みやすい形に変換して表示する機能を持っています。この変換には「org-ruby」というRubyの部品が使われます。
  • org-rubyは、文書の中の「#+TODO:」という行に書かれた言葉を、加工せずにそのまま正規表現の材料にしていました。
  • 細工した言葉を書いておくと、Onigmoの中で繰り返しの番号を数える入れ物(解説では符号付きの16ビット、つまり最大で32,767まで)があふれ、照合のときに確保していない場所への書き込みが起きます。
  • 解説記事によると、GitLabはこれを、GitLabのサービスを動かしているOSのアカウント「git」の権限でのコマンド実行にまでつなげられるとしています。
図:解説記事が紹介する攻撃の流れ
STEP 1細工した.orgファイル公開プロジェクトに置く
STEP 2org-ruby「#+TODO:」の言葉を正規表現に使う
STEP 3Onigmo繰り返しの番号があふれる
STEP 4コマンド実行gitアカウントの権限で
公式の記事ではなく、解説記事の説明にもとづく流れです。

Org-modeは、もともとテキストエディターのEmacsで使われてきた、見出しやTODOの一覧を書くための書式です。GitHubやGitLabは、MarkdownだけでなくOrg-modeやreStructuredTextなど、いくつもの書式の文書を表示できるようになっています。

ふだんOrg-modeを使っていない人がほとんどだと思いますが、「自分は使っていないから関係ない」とはなりません。GitLabにとっては、誰かがリポジトリに置いたファイルを表示するだけで変換の処理が動くからです。

解説記事のひとつは、攻撃には「細工した.orgファイルを含む公開プロジェクトがひとつあればよい」としています。公開プロジェクトは、ログインしていない人でも中身を見られるプロジェクトのことです。攻撃者が自分で公開プロジェクトを作れるGitLab(誰でもアカウントを作れて、公開プロジェクトも作れる設定のもの)では、条件をそろえるのはさほど難しくないことになります。

注意

ただし、これは公式の記事ではなく、検知ルールの説明をもとにした解説記事の内容です。公式の記事は「条件がそろうと」としか書いていないので、この記事でもそこは確定した事実としては扱いません。

また、19.5.1以降の不具合修正の一覧にある「gitlab-markupを2.2.0に、rdocを8.1.0に更新」という項目は、まさに文書を表示用に変換する部品の更新です。公式の記事はこの更新と欠陥の関係をはっきりとは書いていませんが、時期と中身からみて、表示の側でも危ない入力を受け付けないようにする手当てだと考えられます。

ひと月で3回目の「満点」:10月12日のCVE-2026-97229と9月のCVE-2026-85706

夜のエンジニアの机と2台のモニター

今回の件を理解するうえで欠かせないのが、少し前に出た2つの満点の欠陥です。GitLabのセルフマネージドの管理者は、この2カ月ほどのあいだに、深刻度10.0の欠陥に3回向き合ったことになります。

10月12日:CI/CDの設定に書いた正規表現から(CVE-2026-97229)

10月12日、GitLabは19.4.2、19.3.5、19.2.8を緊急のパッチリリースとして公開し、24件の脆弱性を直しました。その筆頭が、CVSS 10.0のCVE-2026-97229です。

  • 名前は「CI/CDの正規表現コンパイラーにおける整数オーバーフロー」で、報告者は今回と同じjoaxcar氏でした。
  • 公式の記事によると、正規表現の確かめ方が不十分だったため、条件がそろうと、CI/CDの設定に書いた細工した正規表現によって、認証されていない利用者がサーバー上でコードを実行できたとされています。
  • 影響を受けたのは19.2から19.4の系列だけでした。

CI/CDは「継続的インテグレーション/継続的デリバリー」の略で、プログラムを書き換えるたびに、自動でテストやビルドを行い、本番の環境に配るところまでをつなげる仕組みです。GitLabでは、リポジトリに「.gitlab-ci.yml」という設定ファイルを置いて、その手順を書きます。この設定の中では、「このフォルダの中のファイルが変わったときだけテストを動かす」といった条件を、正規表現で書けるようになっています。

セキュリティ企業のRapid7は10月16日にこの欠陥の技術的な分析を公開し、CI/CDの設定ファイルの書式を確かめる機能(「ci/lint」という窓口)が、公開プロジェクトでは認証なしで呼び出せる点を入口として示しました。Rapid7は、公式のDockerイメージ(19.4.1)の上で、gitアカウントの権限でコマンドを動かすところまでを自社で再現しています。

一方で、Rapid7が再現した手順では、攻撃者が公開プロジェクトに書き込めることが前提になっており、GitLabの「権限はいらない(PR:N)」という評価とは食い違うと指摘しています。報告の中身が非公開のため、実際の報告がこの前提をどう回避したのかは分からない、とも書いています。

今回のCVE-2026-110264との関係ですが、どちらもjoaxcar氏の報告で、どちらもOnigmoの中で数があふれる種類の欠陥です。10月12日の修正版の不具合修正の一覧にも、「Rubyの正規表現のプログラムサイズの修正」と「範囲付き繰り返しの二重解放の修正」が入っていました。

注意

ただし、公式の記事は2つの欠陥を別のものとして扱っており、10月12日の修正版(19.4.2、19.3.5、19.2.8)は、今回の欠陥の影響を受ける版の範囲に含まれています。つまり、10月12日に急いで当てたサーバーも、もう一度上げる必要があります。

Rapid7の分析では、細工した正規表現を照合させるとワーカー(GitLabの中で要求を処理するプロセス)がおよそ2GiBのメモリーを余分に使い、その後クラッシュするため、応答は502(中継先のエラー)になることが多いとされています。これは今回の欠陥でも参考になる点で、後の節で説明する「ワーカーのクラッシュ」を手がかりにした確認につながります。

9月:認証なしでファイルを読まれる欠陥は、実際に狙われた(CVE-2026-85706)

さらにさかのぼると、9月10日には、リポジトリのコミットの情報を扱う窓口(API)でのパストラバーサルの欠陥CVE-2026-85706が、19.3.2、19.2.6、19.1.8で直されています。パストラバーサルは、ファイルの場所の指定に「../」のような文字を混ぜて、本来は見せないはずのフォルダのファイルを読み出す手口です。

公式の記事によると、条件がそろうと、認証されていない利用者がGitLabのサーバーの任意のファイルを読めたとされ、CVSSは10.0でした。9月23日には、19.0.9と18.11.12にもさかのぼって修正が出ています。

この欠陥は、米国の政府機関CISAの「KEV(悪用が確認された脆弱性の一覧)」に追加されました。BleepingComputerの報道によると、追加は9月11日で、セキュリティ企業のwatchTowrは修正の翌日には、直っていないサーバーを探す試行をインターネット上で観測していました。

  • この報道の時点で確認されていたのは「探す試行」であり、侵入に成功した事例が公に確認されていたわけではありません。
  • ただし、CISAがKEVに入れたということは、CISAとしては悪用の証拠を持っているということです。
  • 読み出されるおそれのあったファイルには、GitLabの設定や秘密の値、CI/CDの認証情報が含まれます。

この3つを並べると、次のようになります。

CVE修正日中身影響を受ける版悪用の状況(10月24日時点)
CVE-2026-857069月10日(9月23日に追加の修正)コミットのAPIのパストラバーサルで、認証なしにファイルを読める18.7以降KEVに追加済み。修正の翌日から探索の試行が観測された
CVE-2026-9722910月12日CI/CDの設定の正規表現の整数オーバーフロー19.2〜19.4GitLabは悪用を報告せず。Rapid7が自社で再現
CVE-2026-11026410月21日正規表現のコンパイラーの整数オーバーフロー7.0以降GitLabは悪用を報告せず。KEVにも入っていない

9月の件が示しているのは、GitLabの満点の欠陥は、修正が出ると数日のうちに狙われうるということです。今回のCVE-2026-110264は、10月24日の時点で悪用の報告はありませんが、10月12日の欠陥の分析がすでに公開されていて、同じエンジンの中の似た種類の欠陥であることを考えると、攻撃の方法が組み立てられるまでの時間は長くないと見ておいたほうがよさそうです。

同時に直された11件の脆弱性

会議室の机に置かれた資料の束とノートPC

10月21日の修正版では、満点の1件のほかに11件の脆弱性が直されています。いずれも19.3.6、19.4.3、19.5.1で直っており、バックポートの版(19.2.9以前)では直っていません。公式の記事に載っている内容を、深刻度の順に表にしました。「EE」とあるものは、有料版の機能を含むEnterprise Editionだけに関係するものです。

CVE深刻度(CVSS)中身影響を受ける版
CVE-2026-15723High(8.2)SAMLとLDAPの自動ひも付けを両方有効にしている場合に、ログインした利用者が、LDAPで管理された他人のアカウントを乗っ取れた10.1以降
CVE-2026-112212High(7.5)OAuth/OIDCの設定情報を返す窓口で共有キャッシュを汚され、一部のログインの流れを外部のサーバーに向けられた(認証不要)18.3以降
CVE-2026-12664Medium(6.8)読み取り専用(read_api)のトークンで、プロジェクトのメール受付用アドレスを取得し、作業項目を作れた18.2以降
CVE-2026-16255Medium(5.9)SAML/LDAPでメンバーを固定する設定をしても、設定前に作られた依頼から、外部でメンバーを追加・承認できた(EE)12.0以降
CVE-2026-105777Medium(4.3)内部向けの応答ヘッダーを通じて、サーバー内部の認証情報を認証なしに取得できた17.6.5以降
CVE-2026-13319Medium(4.3)グループのマイルストーンのAPIで、メンバーでない非公開プロジェクトのタイトルや説明、プロジェクトの場所を読めた15.10以降
CVE-2026-112378Medium(4.3)AIゲートウェイの機能のヘッダーを信用しすぎていたため、契約なしで有料のAI機能を使えた(EE)17.8以降
CVE-2026-105711Low(3.5)公開プロジェクトのマージリクエストから参照された、非公開の課題のタイトルを読めた15.0以降
CVE-2026-14288Low(3.1)保護されたブランチで必須にしたマージリクエストの承認ポリシーを回避できた(EE)17.4以降
CVE-2026-112326Low(3.1)読み取り専用の利用者が、脆弱性の記録を完全に削除できた(EE)17.8以降
CVE-2026-103515Low(2.7)管理者がAmazon Q向けのデータ送信を止めても、グループのオーナーがまた有効にできた(EE)19.2以降

表の中でまず目を通しておきたいのは、High(重要)の2件です。

  • CVE-2026-15723は、社内のアカウントの管理にLDAP(社員の名簿とパスワードをまとめて管理する仕組み。WindowsのActive Directoryなど)を使い、さらにSAML(別のサービスでログインした結果を受け取る仕組み)でのログインも組み合わせている会社で関係があります。この2つの「自動ひも付け」を両方とも有効にしていると、ログインした利用者が、相手の操作なしに他人のアカウントを乗っ取れたとされています。報告はHackerOne経由で、影響は10.1以降と長い期間にわたります。
  • CVE-2026-112212は、OAuthやOIDC(他のサービスにGitLabのアカウントでログインさせるための標準の仕組み)の設定情報を返す窓口で、前段に置いた共有のキャッシュ(同じ応答を使い回して速くするための仕組み)を汚せるというものです。認証なしで仕掛けられ、一部のログインの流れを外部のサーバーに向けられたとされています。GitLabの前にCDNや自前のキャッシュサーバーを置いている構成では、とくに注意が必要です。こちらはGitLab社内の担当者が見つけたものです。

Medium(警告)の中では、CVE-2026-105777が気になります。点数は4.3と低めですが、認証されていない利用者が「サーバー内部の機微な認証情報」を取得できたとされています。

点数だけで後回しにせず、19.3.6以降に上げる理由のひとつとして数えておくべきでしょう。CVE-2026-12664は、読み取り専用のつもりで発行したトークンで、作業項目(課題)を作れてしまうというもので、トークンの権限を絞っても絞った通りに効いていなかった例です。

ポイント

Low(注意)の4件のうち3件と、Mediumの2件は、有料版(EE)の機能に関するものです。無料版(CE)を使っている場合は関係のないものもありますが、CEとEEでは同じ修正版の番号が使われるので、上げる先は変わりません。結局のところ、11件すべてを直すには19.3.6、19.4.3、19.5.1のいずれかに上げる必要がある、という点を覚えておけば十分です。

なお、11件の報告者を見ると、HackerOne経由の外部の研究者が8件、GitLab社内の担当者が3件です。同じ研究者が複数の欠陥を報告している例もあり、GitLabの報奨金の仕組みに多くの研究者が参加していることがうかがえます。

欠陥が毎月のように見つかるのは、裏を返せば、見つけて直す仕組みが働いているということでもあります。問題は、見つかって直されたものを、利用者の側が当てられているかどうかです。

自分のGitLabは対象か:バージョンの確かめ方

白い棚に置かれた小型機器と観葉植物

ここからは、実際にGitLabを動かしている人が手を動かすための手順です。最初にやるのは、自分のGitLabの正確なバージョンを確かめることです。「たしか19.4だったはず」という記憶ではなく、末尾の数字(パッチの番号)まで確かめてください。19.4.2と19.4.3では、今回の欠陥の有無が分かれます。

Webの画面で確かめる

いちばん手軽なのは、GitLabにログインしてヘルプのページを開く方法です。ブラウザで自分のGitLabのアドレスの後ろに「/help」を付けて開くと、ページの上のほうにバージョンが表示されます。管理者であれば、管理エリア(Admin)の概要のページでも、GitLabと関連する部品のバージョンを確かめられます。

サーバーのコマンドで確かめる

Linux用の公式パッケージ(Omnibusと呼ばれる、必要な部品をすべてひとまとめにした形式)で入れている場合は、サーバーにログインして sudo gitlab-rake gitlab:env:info を実行すると、GitLabのバージョンや、使っているRuby、データベースのバージョンなどがまとめて表示されます。もっと簡単には、cat /opt/gitlab/embedded/service/gitlab-rails/VERSION でGitLabのバージョンだけを表示できます。パッケージの管理の道具から確かめる場合は、Debian系なら dpkg -l | grep gitlab、Red Hat系なら rpm -qa | grep gitlab です。

Dockerで動かしている場合は、コンテナの中で同じコマンドを実行します。たとえばコンテナの名前がgitlabなら、docker exec -it gitlab cat /opt/gitlab/embedded/service/gitlab-rails/VERSION です。あわせて、docker ps で表示されるイメージの名前(たとえば gitlab/gitlab-ce:19.4.2-ce.0)も見ておきましょう。

イメージの名前が「latest」になっている場合は、実際にどの版が動いているのかを中のファイルで確かめる必要があります。latestは「取得した時点で最新だった版」を指すだけで、取得し直さない限り古いままだからです。

KubernetesでHelmチャートを使って動かしている場合は、チャートのバージョンとGitLabのバージョンが別の番号になっている点に注意してください。公式の記事によると、19.5.1ではクラウド向けのイメージ(CNG)を使うHelmチャートがv10.5.0に上がっています。helm list でチャートの版を、各ポッドのイメージのタグでGitLabの版を確かめます。

結果の見方

確かめたバージョンを、次の表に当てはめてください。

今のバージョンCVE-2026-110264ほかの11件上げる先の例
19.5.1以上、19.4.3以上、19.3.6以上修正済み修正済み対応不要(次の定期更新を待つ)
19.5.0対象対象19.5.1
19.4.0〜19.4.2対象対象19.4.3
19.3.0〜19.3.5対象対象19.3.6
19.2.9、19.1.9、19.0.10、18.11.13修正済み対象次は19.3.6以上へ
19.0〜19.2の上記より前の版、18.11.12以前対象対象同じ系列のバックポートの版、または19.3.6以上
18.10以前対象(修正版なし)対象アップグレードパスに沿って18.11.13以上へ

なお、GitLab Runner(CI/CDの作業を実際に実行する別のプログラム)は、GitLab本体とは別に入れるソフトです。今回の修正版の一覧には、Runnerそのものの脆弱性は含まれていません。ただし、後の節で説明するように、GitLab本体が乗っ取られた場合はRunnerのトークンも危うくなるので、Runnerを使っている人も他人事ではありません。

アップグレードの前に:バックアップとアップグレードパス

サーバーの横に並ぶ外付けハードディスクとバックアップ機器

修正版に上げる前に、2つの準備をしておきます。ひとつはバックアップ、もうひとつは「どの版を経由して上げるか」の確認です。急いでいるときほど省きたくなる手順ですが、アップグレードに失敗したときに戻れる場所を作っておくことが、結果的にいちばんの近道になります。

バックアップ:データと設定ファイルは別々に取る

GitLabの公式文書によると、Linux用のパッケージで入れている場合のバックアップのコマンドは sudo gitlab-backup create です。これで、データベース、Gitのリポジトリ、CI/CDの成果物やジョブのログ、アップロードされたファイル、Wiki、パッケージやコンテナのレジストリのデータなどが、ひとつのtar形式のファイルにまとめられます。Dockerで動かしている場合は、ホスト側から docker exec -t コンテナ名 gitlab-backup create を実行します。

注意

ここで見落としやすいのが、このバックアップには設定ファイルが入らないという点です。公式文書は、少なくとも /etc/gitlab/gitlab-secrets.json と /etc/gitlab/gitlab.rb を別に保存するよう求めています。

gitlab-secrets.jsonは、データベースの中の暗号化された値(CI/CDの変数や二段階認証の設定など)を解くための鍵を収めたファイルで、これがないと、バックアップから戻しても暗号化された値が読めなくなります。gitlab.rbは、GitLabの設定をまとめたファイルです。

公式文書は、これに加えて次のものも保存しておくことを勧めています。

  • /etc/gitlab/ssl(TLS証明書)
  • /etc/gitlab/trusted-certs
  • SSHのホスト鍵

設定ファイルの一式は sudo gitlab-ctl backup-etc でまとめて保存することもできます。Dockerの場合は、設定のボリューム(公式の手順どおりなら /srv/gitlab/config)を別に保存します。

図:バックアップに入るものと、別に保存するもの
gitlab-backup create に入る
  • データベース
  • Gitのリポジトリ
  • CI/CDの成果物やジョブのログ
  • アップロードされたファイル、Wiki
  • パッケージやコンテナのレジストリのデータ
別に保存する
  • /etc/gitlab/gitlab-secrets.json
  • /etc/gitlab/gitlab.rb
  • /etc/gitlab/ssl、/etc/gitlab/trusted-certs
  • SSHのホスト鍵

もうひとつ大切なのが、バックアップから戻すときは、バックアップを取ったときと「まったく同じバージョンと種類(CEかEEか)」のGitLabにしか戻せないという決まりです。19.4.2で取ったバックアップは、19.4.2のGitLabにしか戻せません。アップグレードに失敗して元に戻したいときは、元のバージョンのパッケージを入れ直してからバックアップを戻すことになるので、元のバージョンの番号を控えておいてください。

なお、gitlab-secrets.jsonは、GitLabの中の秘密を解くための鍵そのものです。バックアップのファイルと同じ場所に置いておくと、バックアップが盗まれたときに中身まで読まれてしまいます。公式文書も、設定ファイルのバックアップはアプリのデータのバックアップとは別の場所に保管するよう勧めています。

仮想マシンの上でGitLabを動かしている場合は、上げる直前に仮想マシンのスナップショット(その時点のディスクの状態をまるごと保存する機能)を取っておくのも、戻し方の選択肢を増やすうえで役に立ちます。ただし、スナップショットは同じ物理ディスクの上にあることが多いので、GitLabのバックアップの代わりにはなりません。

アップグレードパス:飛ばしてはいけない「中継の版」

GitLabは、古い版から新しい版へ一気に飛ぶことができません。途中にいくつかの「必須の中継バージョン(required upgrade stops)」が決められていて、そこを順番に経由する必要があります。中継の版で、データベースの作りを変える処理が行われるためです。この経路のことを「アップグレードパス」と呼びます。

公式文書によると、GitLab 17.5以降は、中継の版が各メジャーバージョンの「x.2」「x.5」「x.8」「x.11」に決まっています。GitLab 18なら18.2、18.5、18.8、18.11、GitLab 19なら19.2、19.5、19.8、19.11です(19.8と19.11はまだ出ていません)。

それより前の版では、17.11.7、17.8.7、17.5.5、17.3.7などが中継の版として挙げられています。中継の版では、その系列の「最新のパッチ」を使うことも決まりのひとつです。たとえば18.11を経由するなら、18.11.0ではなく、その時点の最新の18.11.13を使います。

具体的な経路は、GitLabのサポートチームが用意している「Upgrade Path tool」というWebの道具で、今のバージョンと目標のバージョンを入れると計算してくれます。今回の件に当てはめた例をいくつか挙げておきます(実際に作業するときは、必ずツールで確かめてください)。

今の版今回の欠陥をふさぐ最短の例11件まで直す経路の例
19.4.219.4.319.4.3(同じ)
19.3.419.3.619.3.6(同じ)
19.1.519.1.919.1.9 → 19.2.9 → 19.3.6以上
18.11.1018.11.1318.11.13 → 19.2.9 → 19.3.6以上
18.6.x18.8の最新 → 18.11.13さらに19.2.9 → 19.3.6以上
17.x17.11.7 → 18.2 → 18.5 → 18.8 → 18.11.13(各最新パッチ)さらに19.2.9 → 19.3.6以上

表の下のほうの行のように、古い版を長く使っていた場合は、今回の欠陥をふさぐだけでも何段階もの更新が必要になります。1段ごとにデータベースの移行が入り、次の段に進む前にその移行が終わるのを待つ必要があるので、1日では終わらないこともあります。

作業の途中の版でも外から見えるサーバーは攻撃を受けうるので、古い版から上げる場合は、作業のあいだだけでもインターネットからの接続を絞っておくと安心です。この点は後の節でもう一度取り上げます。

アップグレードの実際:データベースの移行と止まる時間

暗い部屋でターミナル画面を開いたノートPCと小型サーバー

準備ができたら、実際に修正版に上げます。ここでは、セルフマネージドで多い「Linux用の公式パッケージ」と「Docker」の2つの場合について、流れを説明します。

図:更新作業の全体の流れ
STEP 1バージョンの確認末尾の数字まで確かめる
STEP 2バックアップ設定ファイルも別に保存する
STEP 3修正版へ更新番号を指定して上げる
STEP 4移行の完了確認バックグラウンドの移行を待つ
STEP 5ログの確認検知ルールで見る

今回の修正版はデータベースの移行を含む

公式の記事によると、今回のパッチリリースには、データベースの移行(マイグレーション)が含まれています。マイグレーションは、新しい版のプログラムに合わせて、データベースの表の作りを変えたりデータを書き換えたりする処理のことです。通常の移行は19.4.3と19.3.6に含まれ、GitLabが動き始めた後に行う「デプロイ後の移行(post-deploy migration)」は19.4.3に含まれています。

公式の記事は、1台のサーバーですべてを動かしている構成(シングルノード)では、移行が終わるまでGitLabが起動しないため、更新のあいだにサービスが止まると説明しています。複数台で動かしている構成(マルチノード)では、止めずに更新する手順(ゼロダウンタイムでのアップグレード)を使えるとしています。自宅や小さなチームで動かしているGitLabは、ほとんどがシングルノードなので、利用者に「何時から何時まで使えない」と事前に知らせておくのが親切です。

Linux用の公式パッケージの場合

Debian系(UbuntuやDebian)でGitLabの公式リポジトリを登録している場合は、パッケージの一覧を更新したうえで、バージョンを指定して入れます。たとえばEnterprise Editionの19.4.3なら sudo apt-get update の後に sudo apt-get install gitlab-ee=19.4.3-ee.0、Community Editionなら sudo apt-get install gitlab-ce=19.4.3-ce.0 です。

Red Hat系なら sudo dnf install gitlab-ee-19.4.3-ee.0.el9 のように指定します(末尾の部分はOSの版によって変わります)。バージョンを指定せずに入れると、その時点の最新の版に一気に上がろうとし、アップグレードパスを飛ばしてしまうことがあるので、番号を明示するのが安全です。

公式パッケージは、更新のときにデータベースの自動バックアップを取り、移行を実行し、サービスを再起動するところまでを自動で行います。更新が終わったら、sudo gitlab-ctl status で各サービスが動いているかを確かめ、Webの画面の「/help」でバージョンが上がったことを確かめます。

Dockerの場合

Dockerで動かしている場合は、イメージを新しい版のタグに替えてコンテナを作り直します。Docker Composeを使っているなら、設定ファイルのイメージの指定を gitlab/gitlab-ee:19.4.3-ee.0(CEなら gitlab/gitlab-ce:19.4.3-ce.0)のように書き換え、docker compose pull の後に docker compose up -d を実行します。

設定やデータを保存しているボリュームはそのまま使われ、新しいコンテナが起動するときに移行が実行されます。起動の様子は docker logs -f コンテナ名 で追えます。

ここでも、タグに「latest」を使わないことが大切です。latestを使っていると、いつどの版に上がったのかが分からなくなるうえ、アップグレードパスの中継の版を飛ばしてしまうことがあります。今回のように特定の修正版に上げたいときは、番号を明示したタグを使ってください。

次の段に進む前に、バックグラウンドの移行が終わったかを確かめる

GitLabの移行には、更新のときにすぐ終わるものと、更新の後もしばらく裏で動き続ける「バッチ型のバックグラウンド移行」があります。大きな表のデータを少しずつ書き換えるための仕組みで、これが終わる前に次の中継の版に進むと、更新に失敗することがあります。アップグレードパスで何段階も上げる場合は、段ごとにこの確認が必要です。

公式文書によると、Webの画面では、管理エリアの「Monitoring」の「Background migrations」で、待機中(Queued)や仕上げ中(Finalizing)の移行が残っていないか、失敗(Failed)したものがないかを確かめられます。コマンドでは、GitLab 18.9以降なら sudo gitlab-rake gitlab:background_migrations:list、18.8以前なら sudo gitlab-rake gitlab:background_migrations:status で一覧と進み具合を確かめられます。

すべて終わるまで待つ場合は sudo gitlab-rake gitlab:background_migrations:wait が使え、失敗した移行があればエラーで終わります。全文検索にElasticsearchを組み合わせている場合は、メジャーバージョンをまたぐ前に sudo gitlab-rake gitlab:elastic:list_pending_migrations で検索側の移行も確かめる必要があります。

更新の後に確かめること

  • Webの画面の「/help」や gitlab-rake gitlab:env:info で、目標のバージョンになっているか
  • ログインできるか、いくつかのリポジトリを開けるか、git cloneやgit pushが通るか
  • CI/CDのパイプラインを1本動かして、Runnerが作業を受け取れるか
  • バックグラウンドの移行が残っていないか、失敗していないか
  • sudo gitlab-rake gitlab:check SANITIZE=true で、設定やファイルの権限に問題がないか

攻撃されていないかの確認:検知ルールとログの見方

ぼやけたログのグラフを映す2台のモニターとキーボード

修正版に上げると、それ以降は今回の欠陥で攻撃されることはなくなります。しかし、上げる前に攻撃されていたかどうかは、別に確かめる必要があります。とくに、インターネットから誰でもアクセスできる状態で、誰でもアカウントを作れる設定のGitLabを、修正版が出た後もしばらく動かしていた場合は、確認しておきたいところです。

悪用の状況を整理しておく

まず、10月24日の時点で分かっている悪用の状況を、「試行が観測された」と「侵入の成功が確認された」を分けて整理しておきます。

  • GitLabの公式の記事は、CVE-2026-110264が実際の攻撃に使われたとは書いていません。
  • CISAのKEV(悪用が確認された脆弱性の一覧)にも、10月21日の版の時点では入っていないと、複数の解説記事が確かめています。
  • 攻撃の試行が観測されたという報告も、侵入に成功したという報告も、信頼できる情報源では確認できませんでした。
  • GitHubには、この欠陥を対象にしたと名乗る検証用のコードがいくつか公開されています。そのうちのひとつは、Ruby 3.4.11の上でOnigmoをクラッシュさせるところまでを確かめたもので、作者自身が「クラッシュまでで、攻撃に使える形にはしていない」「遠隔でのコード実行の道筋は示していない」と説明しています。また、別の検証用のコードについては、説明の中で10月12日の欠陥を対象にしていると書かれており、今回の欠陥に有効かどうかは確かめられていないと指摘する解説記事があります。

つまり、「攻撃に使える公開のコードはまだ確認されていないが、欠陥の場所に迫る材料は出そろいつつある」という状態です。9月の欠陥では、修正の翌日には探索の試行が観測されたことを思い出しておきましょう。

GitLabが公開した2つの検知ルール

GitLabは公式の記事の中で、セルフマネージドの利用者向けに2つの検知ルールを公開しています。「TLDR」というGitLabのセキュリティチームが公開している検知の枠組みに収められたもので、名前は次のとおりです。

  • Onigmo native worker crash(Onigmoのネイティブなワーカーのクラッシュ)
  • Org mode render error burst(Org-modeの表示エラーの急増)

公式の記事そのものには、それぞれのルールが何を探すのかの説明はなく、詳細は検知ルールのファイルの側に書かれています。解説記事によると、前者はGitLabのWebの処理を受け持つPuma(プーマ、RubyのWebサーバー)のエラー出力のログ puma_stderr.log に、Onigmoの中でのクラッシュの記録が出ていないかを見るもので、後者は例外の記録のログ exceptions_json.log に、.orgファイルの表示の時間切れやエラーが短い間に集中して出ていないかを見るものとされています。Linux用の公式パッケージなら、これらのログは /var/log/gitlab/puma/ や /var/log/gitlab/gitlab-rails/ の下にあります。

ログを手で眺める場合の目安として、たとえば sudo grep -il onigmo /var/log/gitlab/puma/puma_stderr.log* でクラッシュの痕跡を、sudo grep -c '\.org' /var/log/gitlab/gitlab-rails/exceptions_json.log で.orgファイルに関わる例外の件数を、ざっと数えることができます。ログは古い分が圧縮されて残っていることが多いので、zgrep も使いましょう。

ただし、これは目安にすぎず、正式な確認にはGitLabの検知ルールそのものを使ってください。10月12日の欠陥についてRapid7が指摘した「Workhorseのログで長い時間かかった要求の後に502が返り、同じ時刻にPumaのワーカーが再起動している」という組み合わせも、参考になる手がかりです。

痕跡がなくても安心はできない

注意

解説記事によると、GitLab自身も、攻撃が成功した場合には目立った痕跡が残らないことがあると注意しています。ログにクラッシュの記録がないことは、攻撃されていないことの証明にはなりません。

そこで、ログに加えて次のような点も確かめておくと安心です。

  • 最近作られた、あるいは最近更新された.orgファイルを含むプロジェクトがないか。とくに、見覚えのないアカウントが作った公開プロジェクトはないか
  • 最近作られたアカウントや、急に管理者の権限を持ったアカウントがないか(管理エリアの「Users」で、作成日や最終ログインの日時で並べ替えて見られます)
  • GitLabのサーバーで、gitアカウントが見覚えのないプロセスを動かしていないか、外部へ見覚えのない通信をしていないか
  • cronや起動時に動くスクリプトなど、居座るための仕掛けが増えていないか

不審な点が見つかった場合は、ひとりで消して回るのではなく、まずサーバーをネットワークから切り離し、ログやディスクの状態を保存してから、社内のセキュリティの担当者や専門の会社に相談してください。消してしまうと、何をされたのかを後から確かめられなくなります。

乗っ取られていたら何が漏れるか:トークンと秘密情報の入れ替え

作業台に並ぶ小型コンピューターとネットワークスイッチ

GitLabのサーバーが乗っ取られた場合に深刻なのは、ソースコードが読まれることだけではありません。GitLabには、ソースコードを本番の環境に届けるための鍵が集まっているからです。解説記事によると、GitLabは今回の欠陥が悪用された場合の影響として、GitLabの中の秘密の値、すべてのCI/CDの変数、Runnerのトークン、アクセストークンの盗難と、すべてのリポジトリへのアクセスを挙げています。

GitLabの中にある主な鍵の種類を、公式文書の「トークンの概要」をもとに整理しておきます。トークンには種類ごとに決まった頭文字(プレフィックス)が付いているので、漏れた文字列がどの種類のものかを見分ける手がかりにもなります。

種類頭文字何に使うか入れ替え方の例
Runnerの認証トークンglrt-RunnerがGitLabに自分を名乗るための鍵。Runnerの設定ファイルに保存されるRunnerのAPIで作り直すか、Runnerを登録し直す
個人のアクセストークンglpat-人の代わりにAPIやGitの操作をする鍵。作った人の権限を引き継ぐ画面またはAPIで無効にして作り直す
プロジェクト/グループのアクセストークンglpat-特定のプロジェクトやグループ専用の鍵画面またはAPIで無効にして作り直す
デプロイトークンgldt-リポジトリやパッケージ、コンテナのイメージを取得・送信するための鍵画面で取り消して作り直す
CI/CDのジョブトークンglcbt-ジョブの実行中だけ使える短命の鍵ジョブの終了で自動的に無効
OAuthのアプリの秘密gloas-GitLabのアカウントでほかのサービスにログインさせるための値アプリの設定で作り直す

Runnerのトークンの扱い

GitLab Runnerは、CI/CDのジョブを実際に動かすプログラムで、GitLabのサーバーとは別のマシンで動かすことが多いものです。Runnerは、登録のときに受け取った認証トークン(glrt-で始まる文字列)を設定ファイル(Linuxなら多くの場合 /etc/gitlab-runner/config.toml)に保存し、それを使ってGitLabに「仕事はありませんか」と問い合わせ続けます。公式文書は、Runnerのマシンのファイルを読める人がいれば、このトークンを読み取ってRunnerの「なりすまし」を作れると注意しています。

Runnerのなりすましができると、そのRunnerに回されるはずだったジョブを攻撃者が受け取れるようになります。ジョブには、テストやデプロイのためにCI/CDの変数(クラウドのキーや本番のデータベースのパスワードなど)が渡されることが多いので、これが盗まれる入口になります。GitLabのサーバーが乗っ取られたおそれがある場合は、Runnerの認証トークンも作り直しておくべきです。

公式文書は、RunnerのAPIで認証トークンを作り直したり無効にしたりできるとしています。具体的には、Runnerの番号を指定して POST /api/v4/runners/:id/reset_authentication_token を呼ぶ方法があり、作り直した後はRunnerの設定ファイルの値を新しいものに書き換えて、sudo gitlab-runner restart で再起動します。Runnerの数が少なければ、管理画面でRunnerを削除してから登録し直すほうが分かりやすいかもしれません。

ふだんの運用の面では、Runnerを用途ごとに分けておくことも大切です。誰でもプロジェクトを作れるGitLabで、すべてのプロジェクトが使える共有のRunnerに本番環境へのデプロイも任せていると、ひとつの公開プロジェクトから本番の鍵まで届いてしまうおそれがあります。本番に触れるジョブは、特定のプロジェクトだけが使える専用のRunnerに回し、保護されたブランチからしか動かないようにしておくと、被害の広がりを抑えられます。

入れ替えの順番

乗っ取られたおそれがあると判断した場合は、次の順番で鍵を入れ替えます。順番を守らないと、新しい鍵もまた盗まれる、あるいは古い鍵が使えるまま残る、といったことが起きます。

  1. まず修正版に上げ、サーバーそのものが安全な状態になったことを確かめる(乗っ取られていた場合は、きれいな環境に作り直してからバックアップを戻すことも検討する)
  2. CI/CDの変数に入れていた外部の鍵(クラウドのキー、データベースのパスワード、外部サービスのAPIキーなど)を、それぞれのサービスの側で古いものを無効にしてから新しく作り、GitLabに登録し直す
  3. Runnerの認証トークンを作り直し、Runnerの設定を書き換える
  4. 個人・プロジェクト・グループのアクセストークン、デプロイトークンを無効にして作り直す。とくに管理者のトークンは必ず入れ替える
  5. 利用者全員にパスワードの変更と、二段階認証の設定の見直しを求める
  6. リポジトリの中身やパイプラインの設定(.gitlab-ci.yml)が、知らないうちに書き換えられていないかを確かめる

2番目の「古いものを無効にしてから新しく作る」は、関連記事の「”Black October”の10日間」で取り上げた、クラウドサービスZeaburが利用者に求めた手順と同じ考え方です。新しい鍵を作っただけでは、盗まれた古い鍵は使えるまま残ります。

6番目のリポジトリの確認も見落とせません。サーバーを乗っ取った攻撃者は、ソースコードに悪意のあるプログラムを紛れ込ませたり、パイプラインの設定を書き換えて、次にビルドされる成果物に細工をしたりできます。

GitLabの中で作ったものを社外に配っている場合は、その配布物を受け取った人まで被害が広がる、いわゆるサプライチェーン攻撃の入口になりかねません。重要なリポジトリについては、手元の作業用のコピーや別の場所の複製と見比べて、身に覚えのないコミットがないかを確かめてください。

外部公開の見直しと、立場別にやること

機器のポートに差し込まれたネットワークケーブル

最後に、今回の件をきっかけに見直しておきたい「GitLabをどこまで外に見せているか」と、立場ごとにやることをまとめます。この2カ月で満点の欠陥が3回出たことを考えると、次の欠陥が出たときに慌てずに済むように、ふだんの設定を整えておくことが大切です。

そもそもインターネットに出す必要があるか

今回の欠陥も、9月と10月12日の欠陥も、「ログインしていない人が、ネットワーク越しに」攻撃できるものでした。裏を返せば、GitLabにたどり着けるのが社内のネットワークやVPN(仮想の専用回線)の内側の人だけなら、インターネット上の不特定多数の攻撃者からは手が届きません。

社内の開発チームだけが使うGitLabなら、インターネットに直接さらさず、VPNや、許可した相手だけを通す仕組み(ゼロトラスト型のアクセスの仕組みなど)の内側に置くことを検討してください。自宅で動かしている場合も、ルーターのポート開放でGitLabを外に出していないかを確かめ、外から使いたいならVPNやTailscaleのような仕組みを経由するほうが安全です。

どうしても外に出す必要がある場合も、ファイアウォールで接続元のIPアドレスを絞る、管理者のページへの接続を社内に限る、といった工夫で、攻撃を受けられる範囲を小さくできます。ただし、これらは攻撃される機会を減らすものであって、欠陥を直すものではありません。修正版に上げることの代わりにはならない点に注意してください。

誰でもアカウントを作れる設定になっていないか

今回の欠陥では、解説記事が「細工したファイルを含む公開プロジェクトがひとつあればよい」と指摘し、10月12日の欠陥では、Rapid7が「攻撃者が公開プロジェクトに書き込めること」を再現の前提にしていました。どちらも、外部の人がアカウントを作り、公開プロジェクトを作れるGitLabほど条件がそろいやすくなります。

GitLabの管理エリアの「Settings」の「General」には、「Sign-up restrictions(登録の制限)」という項目があります。ここで新規登録を無効にするか、少なくとも管理者の承認を必須にする、登録できるメールアドレスのドメインを自社のものに限る、といった設定ができます。

同じ画面の「Visibility and access controls(公開範囲とアクセスの管理)」では、「Restricted visibility levels(使えない公開範囲)」で「Public(公開)」を選び、管理者以外が公開プロジェクトを作れないようにすることもできます。すでにある公開プロジェクトは自動では非公開にならないので、管理エリアのプロジェクトの一覧で公開範囲を確かめ、必要のないものは「Internal(ログインした人だけ)」や「Private(メンバーだけ)」に変えましょう。

オープンソースのプロジェクトをGitLabで公開している場合など、公開をやめられない事情もあると思います。その場合は、修正版をいち早く当てることがいっそう大切になります。

次の緊急版に備えて

  • GitLabのセキュリティのお知らせを受け取れるようにしておく(GitLabの公式サイトでは、セキュリティのお知らせをメールやRSSで受け取る手段が用意されています)
  • 今のバージョンと、次の中継の版を、いつでも言えるようにしておく。古い版にとどまるほど、緊急時に何段階も上げる羽目になる
  • バックアップと設定ファイルの保存を定期的に自動で行い、実際に戻せるかを年に一度は試す
  • テスト用のGitLabを1台用意できるなら、本番より先にそこで更新を試す
  • CI/CDの変数に入れる鍵は、使える範囲と期限を絞り、保護されたブランチだけに渡す設定にする

立場別にやること

ここまでの内容を、立場ごとに表にまとめておきます。

立場まずやること余裕があればやること
GitLab.comだけを使っている人対応は不要。GitLab.comは修正済み自分のアクセストークンの権限と期限を見直す
自宅でGitLabを動かしている人バージョンを確かめ、設定ファイルを含めてバックアップを取り、修正版に上げるポート開放をやめてVPN経由にする。新規登録を無効にする
社内のGitLabの管理者修正版に上げ、バックグラウンドの移行の完了と検知ルールでのログを確かめる11件すべてを直すため19.3.6以上へ。登録の制限と公開範囲を見直す
古い版(18.10以前)を使っている管理者Upgrade Path toolで経路を出し、作業中は外部からの接続を絞る定期的に中継の版まで上げる運用に切り替える
Runnerやデプロイを管理している人不審な点があればRunnerの認証トークンとCI/CDの変数の鍵を入れ替える本番向けのジョブを専用のRunnerと保護されたブランチに限る
GitLabを使う開発者見覚えのないコミットやパイプラインの変更がないか確かめる個人のアクセストークンに期限を付け、使っていないものを消す

GitLabの運用を体系的に学ぶなら:GitLab実践ガイド 第2版

ここまで、今回の欠陥への対応を中心に書いてきましたが、「そもそもGitLabのCI/CDやRunnerの仕組みがよく分からないまま動かしている」という方もいると思います。そうした方には、インプレスから出ている『GitLab実践ガイド 第2版 The DevSecOps Platformの導入と運用』(北山晋吾・棚井俊 著、2024年3月刊、ISBN 978-4-295-01857-5)が参考になります。インプレスの公式ページの紹介をもとにした特徴は、次のとおりです。

  • GitLabを、リポジトリの管理だけでなく、コードの更新をきっかけにした継続的インテグレーションや継続的デプロイのジョブまで含めて、開発の流れ全体を良くする道具として解説しています。
  • 利用者向けのリポジトリの機能に加えて、デプロイの運用を効率よくするために必要な情報も扱っていると紹介されています。
  • 目次は「The DevSecOps Platform」「GitLabの導入」「GitLabを使ってみよう」「GitLab CI/CDを動かしてみる」「開発計画」「継続的インテグレーション」「開発レビュー」「継続的デリバリ」の8章で、導入から日々の運用までを順に追える構成です。
  • 紙の本(B5変形判、312ページ)のほか、PDFの電子版も用意されています。

GitLab実践ガイド 第2版をAmazonで見る

なお、この本は2024年3月の刊行なので、GitLab 19の画面や、今回のような最新の欠陥の話は含まれていません。画面の細かな位置や設定の名前は変わっていることがあるので、具体的な操作は公式文書とあわせて確かめてください。CI/CDやRunnerの考え方を一度まとめて押さえておくと、今回のような修正の記事を読んだときに、どの部分が自分の環境に関係するのかを判断しやすくなります。

まとめ

2026年10月21日、GitLabは緊急のパッチリリースで、CVSS 10.0のCVE-2026-110264を含む12件の脆弱性を直しました。CVE-2026-110264は、Rubyの正規表現エンジンOnigmoが関わるとみられる整数オーバーフローで、認証なしでサーバー上のコードを実行されうるものです。影響は2014年のGitLab 7.0以降のほぼすべての版に及び、10月12日に出た別の満点の欠陥(CVE-2026-97229)の修正版でも直っていません。

解説記事は、Org-modeの文書ファイルの表示が入口だとしていますが、公式の記事は「条件がそろうと」としか書いていません。

10月24日の時点で、GitLabは悪用を報告しておらず、CISAのKEVにも入っていません。ただし、9月の満点の欠陥では修正の翌日から探索の試行が観測され、KEVに追加されました。同じエンジンの似た欠陥の分析もすでに公開されているので、時間の余裕はあまりないと考えておくのが無難です。

  • まず末尾の数字までバージョンを確かめ、19.5.1、19.4.3、19.3.6、19.2.9、19.1.9、19.0.10、18.11.13のいずれか以上に上げる
  • 上げる前に gitlab-backup create でデータを、gitlab-secrets.json と gitlab.rb を別に保存する
  • 18.10以前の版はUpgrade Path toolで中継の版を確かめ、段ごとにバックグラウンドの移行の完了を待つ
  • 同時に直った11件まで直すには、19.3.6、19.4.3、19.5.1のいずれか以上が必要
  • GitLabの2つの検知ルールでログを確かめ、不審な点があればRunnerのトークンとCI/CDの変数の鍵を、古いものを無効にしてから入れ替える
  • インターネットへの公開、誰でも登録できる設定、公開プロジェクトの作成を見直す

GitLabのような開発の土台は、一度入れると「動いているから触らない」状態になりがちです。けれども、そこにはソースコードと本番への鍵がまとまっていて、攻撃する側から見ればとても割のいい標的です。今回の件を、自分のGitLabのバージョンとバックアップ、公開の範囲を見直すきっかけにしてみてください。

出典

※この記事の内容は、2026年10月24日時点で公表されている情報をもとにしています。