この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
Apache Flinkの脆弱性「CVE-2026-35194」が2026年5月15日に公開されました。重要度はApache公式評価で「クリティカル」、CVSS v3.1は8.1(CISA-ADP評価)です。SQL生成時の文字列エスケープ処理の不備で、クエリ送信権限を持つ認証済みユーザーが細工したSQL文を送ると、TaskManager上で任意コード実行(RCE)が成立します。
影響範囲は1.15.0~1.20.3、2.0.0~2.2.0(RC1・RC2含む)と広く、現役の運用クラスタはほぼ全部が射程に入ります。私の現場感覚で言うと、これは「クラスタ全停止して当ててから帰る」レベルの脆弱性です。
この記事では、Apache Flinkを動かしているLinux管理者の視点で、なぜこの脆弱性が深刻なのか、自分のクラスタが踏まれていないかをどう確認するか、復旧と恒久対応をどう設計するかをまとめます。
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
CVE-2026-35194の概要
NVDの原文の要旨はシンプルです。「Apache FlinkのSQLコード生成にコードインジェクションがある。クエリ送信権限を持つ認証済みユーザーが、悪意のあるSQLクエリを通じてTaskManager上で任意コードを実行できる」。これだけ読むと「認証必須なら大したことない」と受け取られがちですが、現場ではそうはなりません。
影響を受けるバージョン範囲
| 系統 | 影響を受けるバージョン | パッチ提供バージョン |
|---|---|---|
| 1.20系 | 1.15.0 ~ 1.20.3 | 1.20.4 |
| 2.0系 | 2.0.0 ~ 2.0.1 | 2.0.2 |
| 2.1系 | 2.1.0 ~ 2.1.1 | 2.1.2 |
| 2.2系 | 2.2.0(RC1・RC2含む) | 2.2.1 |
1.15.0は2022年5月リリースなので、約4年分のFlinkクラスタが対象です。「うちは古いから関係ない」が逆に成立しないのが特徴です。
CVSSと攻撃ベクトル
CVSS v3.1のベクトル文字列は `AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N` です。ネットワーク経由で、攻撃複雑性は低く、必要な権限は「Low」、ユーザー操作は不要。機密性と完全性はHigh。可用性だけがNoneですが、これは「クラッシュを目的とせずRCEで奪取する系」の典型ベクトルで、可用性Noneだから安心ではなく、むしろ「気づかれず取りに来る」ベクトルだと読むのが正しいです。
一次情報の整理
本件のソースは現時点で4本に整理できます。
- NVD CVE-2026-35194: 公的データベース。CVSSベクトルと影響バージョン範囲の正本。
- Apache Flink Security: Apache公式アドバイザリ。パッチバージョンと推奨アップグレードパスの一次情報。
- CVE.org Record: MITREの正式レコード。
- Security NEXT記事: 国内媒体での補足。JSON関数とESCAPE句付きLIKE式が影響範囲だと明示。
Security NEXTが踏み込んで書いている「JSON関数の処理」「ESCAPE句を伴うLIKE式」の2点は、検知ルールを書く現場には重要な手がかりです。SQLログを全部見るのではなく、まずJSON関数とESCAPE句付きLIKEを通すクエリに絞って確認できるからです。
技術的本質:なぜSQLからJVMが取られるのか
Flink SQLは、入力されたSQL文をパースして、内部的にJavaコードを生成(コードジェネレーション)し、それをJVM上でコンパイル・実行することで高速化しています。つまりFlink SQLは「単にSQLを評価する」のではなく「SQLからJavaを書き出してJVMで走らせる」アーキテクチャです。
ここで文字列リテラルをコード生成時に展開する処理に、エスケープ漏れがありました。攻撃者がリテラル領域に細工した文字列を仕込むと、コード生成器が出力するJavaソースの構造を壊し、攻撃者の意図したJavaコードがそのまま生成・実行されてしまいます。生成されたコードはTaskManager(実際にデータ処理を行うワーカープロセス)のJVMで走るため、結果としてTaskManagerプロセスの権限で任意コード実行が成立します。
SQLインジェクションの古典型が「アプリのバックエンドDBに余計なSQLを混ぜ込む」のに対し、CVE-2026-35194は「Flinkのコード生成器に余計なJavaを混ぜ込む」攻撃です。出口がDBではなくJVMという点で、被害の質が一段重くなります。
Linux管理者の検知と一次対応
Flinkクラスタを実際に運用しているLinux管理者がやるべきことを、優先順位順に整理します。
1. バージョン即時確認
JobManagerが動いているホストで、まずバージョンを確定します。
# Flinkインストールディレクトリで
./bin/flink --version
# REST API経由で確認(JobManagerのデフォルトポート8081)
curl -s http://localhost:8081/config | python3 -m json.tool | grep flink-version
出てきたバージョンが影響範囲なら、次に進みます。
2. クエリ送信元の棚卸し
本脆弱性は「認証済みでクエリ送信権限のあるユーザー」が前提です。ここで止まりがちな質問が「うちのFlinkは認証かけてたっけ?」です。
Flinkは標準では認証機構を持たず、REST APIは無認証で開いていることが多いです。前段にリバースプロキシでBasic認証や相互TLSをかけているか、社内ネットワークから絞り込んでいるか、運用次第で実質的な前提が変わります。
# JobManager REST APIの公開状況を確認
ss -tlnp | grep 8081
# 全インターフェイスでLISTENしていたら危険信号
# 0.0.0.0:8081 ではなく 127.0.0.1:8081 + プロキシ経由が安全
もし0.0.0.0でLISTENしていて、認証もかけていなければ、本脆弱性は実質的に「未認証RCE」相当として扱う必要があります。NVDは「認証必須」と書いていますが、Flinkにそもそも認証機構が組み込まれていない以上、運用側で認証を担保していなければ前提は崩れます。
3. 直近のSQLジョブ監査
JSON関数とESCAPE句付きLIKE式を含むSQLジョブが、直近どれだけ流れたかを確認します。
# Flinkのログから疑わしいSQLパターンを抽出
grep -iE "JSON_|LIKE.*ESCAPE" /opt/flink/log/flink-*-sql-client-*.log
grep -iE "JSON_|LIKE.*ESCAPE" /opt/flink/log/flink-*-taskexecutor-*.log
# REST APIから直近のジョブ一覧を取得
curl -s http://localhost:8081/jobs/overview | python3 -m json.tool
見覚えのないジョブIDや、業務時間外に投入されたジョブがあれば、ジョブ詳細を引いて投入元・SQL文を確認します。クエリ送信権限を持つ正規ユーザーのアカウントが乗っ取られているケースも想定して、踏み台になっていないかを並行で見るのが筋です。
4. TaskManagerプロセス挙動の確認
RCEが成立していれば、TaskManagerのJVMから外部プロセス起動や外向き通信が走ります。
# TaskManagerプロセスの子プロセスを確認
ps -ef --forest | grep -A 20 TaskManagerRunner
# TaskManagerからの外向きTCPコネクション
ss -tnp | grep $(pgrep -f TaskManagerRunner)
本来TaskManagerが話す相手はJobManagerと、入出力のKafka/HDFS/JDBCといった既知のシンクだけです。それ以外のIPに対する443/80以外の常駐コネクションがあれば、要調査です。
Amazonアフィリエイト書籍(学習用)
PR|ストリーム処理の設計思想を体系的に学びたい方へ
スケーラブルリアルタイムデータ分析入門 ─ラムダアーキテクチャによるビッグデータ処理(Nathan Marz, James Warren著/オライリージャパン)
Apache Stormの作者本人が書いた本。Flinkと並ぶストリーム処理基盤の設計思想・ラムダアーキテクチャを横串で押さえられます。CVE対応の合間に読むと、なぜFlink SQLが「コード生成→JVM実行」という構造を取らざるを得ないのか腹落ちします。
恒久対応の設計
パッチ当ては最優先ですが、それだけで終わらせない設計を入れておくのが、次のCVEを生き延びるコツです。
1. パッチ適用
影響系統に応じて、以下のいずれかへアップグレードします。
- 1.20系運用: 1.20.4へ
- 2.0系運用: 2.0.2へ
- 2.1系運用: 2.1.2へ
- 2.2系運用: 2.2.1へ
マイナー版上げなのでAPI互換は保たれますが、本番適用前にステージングで既存ジョブのリスタート挙動とチェックポイント互換を必ず検証します。Flinkはステートを抱えるアプリケーションなので、サーバ単体のyum updateとは段取りが違います。
2. クエリ送信権限の最小化
そもそも「誰でもSQLを投げ込める」状態を許していたなら、それを止めます。Flink SQL Gatewayを前段に置き、認証・認可を入れ、ロールベースでクエリ送信権限を絞ります。マルチテナントで使っているなら、テナント間のジョブ分離も併せて見直します。
3. ネットワーク層での閉じ込め
JobManager REST API(8081)とTaskManagerのデータポート(6121-6125、設定値による)は、社内VPC・社内VLAN内に閉じ込めます。インターネット直公開は論外です。Linuxサーバ側でfirewalldかnftablesで明示的に絞り、kubectl exec越しの内部経路だけ通します。
# nftablesで8081を社内サブネットだけに絞る例
nft add rule inet filter input ip saddr 10.0.0.0/8 tcp dport 8081 accept
nft add rule inet filter input tcp dport 8081 drop
4. SQL監査ログの保存
Flinkはデフォルトだと、SQLジョブ単位の投入履歴を残しません。SQL Gatewayかカスタムハンドラを噛ませて、SQL本文を別ストレージに長期保存します。次のSQL系CVEが出た時、「過去30日分のSQLを全部grepする」ができると、影響有無の判断が一気に早くなります。
教訓:分散処理基盤のCVEはサーバCVEと別ロジックで運用する
Linuxサーバの脆弱性は、yum updateとサービス再起動でだいたい片付きます。Flinkのような分散処理基盤の脆弱性は、それと同じノリで進めると詰まります。
状態を持つストリームアプリは、勝手に止めるとデータロストかリプレイ地獄が待っています。チェックポイント・セーブポイントを取り、ステートを失わないアップグレード手順を組む必要があります。CVE-2026-35194のような「クラスタを止めてでも当てるべき」案件で、止め方を準備していなかったために対応が1週間延びる、というのが分散処理基盤の典型的な事故パターンです。
普段から、セーブポイント保存→停止→アップグレード→セーブポイントから再開、の手順書を持っているかどうかで、CVE発生時の初動が10倍変わります。今回のCVEを機に、自分のチームでこの手順書が動かせるかを試しておくと、次の事故で助かります。
私自身、20年以上Linuxの現場でデータ基盤を触ってきましたが、SQLからJVMが取られるという経路はやはり気持ちが悪いです。気持ちの悪さを言語化して、検知ルールと運用手順に落とし込めるかどうかが、ベテランと一般管理者の境目になります。
PR
Java[完全]入門(松浦健一郎・司ゆき著/SBクリエイティブ)
Flink SQLが内部でJavaコードを生成しJVMで走らせる構造を読み解くなら、Java言語そのものへの理解が前提になります。本書は開発環境から実務レベルまで600ページで体系化されており、コード生成器が吐くJavaソースを「読める側」に立つための土台になります。
Linuxセキュリティ運用を体系的に学びたい方へ
リナックスマスター.JPでは、Linuxサーバ運用の基礎から、分散処理基盤やコンテナを含む現場のセキュリティ対応までを、ハンズオン中心の有料セミナーで学べます。CVE速報を「読む側」から「対応する側」へ抜けるための、実践的なカリキュラムを揃えています。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。
登録無料・いつでも解除できます