当社のAIエンジンNeutronが、UCバークレーのCyberGymベンチマークで97.1%のスコアを記録しました。 詳細を見る

ディープダイブ

ディープダイブ

Greeter フレームワークに悪用された Flowise の RCE(CVE-2024-58351)

Flowise 2.1.4 より前では overrideConfig が Custom JS Function ノードの JavaScript を置き換えられ、Greeter が悪用しました。2.1.4 で修正済みです。

要点

  • CVE-2024-58351 では、推論リクエストが Flowise の Custom JS Function ノードの JavaScript を置き換え、サーバーがそのコードを実行します。原因は、リクエストの overrideConfig フィールドに許可リストがないことです。
  • Flowise の 2.1.4 より前のすべてのリリースが影響を受けます。Era はインターネットに公開された Flowise インスタンスを 4,372 件数え、バージョンを読み取れた 3,277 件のうち 703 件に認証がありませんでした。
  • VulnCheck はこの脆弱性を CVSS v3.1 9.8 Critical と評価しています。Greeter フレームワークは 2026 年 7 月から 10 月にかけてハニーポットで悪用し、VulnCheck の KEV カタログに掲載されています。CISA の KEV カタログには 2026 年 11 月 8 日時点で掲載されていません。
  • 2.1.4 以降に更新してください。できれば 3.1.4 を使用してください。同じコード経路の 2026 年の強化も含まれます。「修正方法」を参照してください。

影響を受けますか?

Flowise の 2.1.4 より前のリリースを実行し、信頼できないユーザーが推論 API に到達できる場合に影響を受けます。次の条件がすべて当てはまる必要があります。

  • npm パッケージ flowise、公式 Docker イメージ、またはそれを組み込んだ製品として、2.1.4 より前の Flowise を実行している。
  • 推論エンドポイント POST /api/v1/prediction/<chatflow-id> に、直接または埋め込みチャットウィジェット経由で信頼できないユーザーが到達できる。
  • それらのユーザーが利用できるチャットフローに Custom JS Function ノードがある、またはアプリケーションレベルの認証が無効なために自分で作成できる。

影響を受ける 1.x および 2.0.x 系のアプリケーションレベルの認証は FLOWISE_USERNAME と FLOWISE_PASSWORD の組で、両方の変数が未設定のときは無効です。Era のハニーポットは両方の変数を未設定にして Flowise 1.8.2 を実行しており、記録された攻撃は Custom JS Function ノードを含むチャットフローを使用しました。

公開された母集団では、認証なしの例が一般的です。Era の調査では、インターネット上の Flowise インスタンスが 4,372 件見つかり、3,277 件からバージョンを読み取れ、そのうち 703 件に認証がありませんでした。703 件のうち 46 件は、Era が再現した脆弱な構成と一致しました。

観測された Flowise インスタンス 4,372 件、バージョンを読み取れた 3,277 件、認証なしの 703 件、脆弱な構成に一致した 46 件の棒グラフ
図 1: Era が観測した公開 Flowise 群と、この脆弱性に一致する認証なしの部分集合。出典: Era Security、2026 年 11 月 3 日

系列 影響を受けるバージョン 修正バージョン
1.x すべてのリリース 2.1.4(2024-11-13)
2.0.x すべてのリリース 2.1.4(2024-11-13)
2.1.x 2.1.0 から 2.1.3 2.1.4(2024-11-13)
2.1.4 以降 CVE-2024-58351 の影響なし 2026 年の強化を含む 3.1.4 以降を実行

コンテナや他の製品に組み込まれたコピーを含め、すべてのインストールでパッケージのバージョンを確認してください。

# Global npm install
npm ls -g flowise

# Project install
npm ls flowise

# Docker: read the version inside the running container
docker exec <container> cat /usr/local/lib/node_modules/flowise/package.json | grep '"version"'

# Running instance
curl -s http://localhost:3000/api/v1/version

バージョンエンドポイントはサーバー上の最も近い package.json を読むため、プロセスが実際に実行しているパッケージを示します。イメージが古いパッケージからビルドされている場合、コンテナイメージのタグだけでは不十分です。

修正方法

2.1.4 以降に更新し、同じ関数に対する 2026 年の強化コミット 2 件を含む現在の 3.1.4 を使用してください。その後、すべてのチャットフローで設定の上書きが無効になっていることを確認します。

  1. パッケージを更新します。グローバルインストールでは npm install -g flowise@3.1.4 を実行します。プロジェクトのインストールでは npm install flowise@3.1.4 を実行します。Docker では現在の flowiseai/flowise イメージを取得し、データボリュームを保持したままコンテナを再作成します。
  2. 各チャットフローを開き、設定、構成、Security タブの順に確認します。2.1.4 以降、設定の上書きはデフォルトで無効です。上書きを許可する必要があるノードパラメータだけを有効にします。許可リストはチャットフローごと、ノード種別ごとに保存されます。
  3. インスタンスの前に認証を置きます。影響を受ける系列では FLOWISE_USERNAME と FLOWISE_PASSWORD を設定し、3.x では管理者アカウントを作成します。推論 API は必要なネットワークだけに制限します。
  4. すぐに更新できない場合は、リバースプロキシで信頼できないクライアントからの POST /api/v1/prediction を遮断し、公開チャットフローを無効にし、それらのクライアントが到達できるすべてのフローから Custom JS Function ノードを外します。これらの措置は入口を減らしますが、コードは修正しません。

回避策には限界があります。認証だけでは脆弱性は解消しません。チャットフローを作成できるアカウントは Custom JS Function ノードを追加して上書きを送信できます。影響を受ける 1.x および 2.0.x 系のアプリケーション認証は単一の管理者アカウントなので、管理者パスワードが 1 つ漏えいすれば十分です。そのため、修正は更新であり、プロキシでの遮断は一時的な措置です。

根本原因は何ですか?

推論 API はリクエストのフィールドを信頼された設定として扱い、その設定が実行可能なコードを置き換えられます。Flowise のチャットフローはノードのグラフであり、Custom JS Function ノードには javascriptFunction という入力があり、その値は JavaScript のソースコードです。2.1.4 より前は、リクエスト本文の overrideConfig オブジェクトが許可リストなしですべてのノード入力に適用されていました。次は Flowise 2.1.3 の packages/server/src/utils/index.ts からの引用です。

export const replaceInputsWithConfig = (flowNodeData: INodeData, overrideConfig: ICommonObject) => {
    const types = 'inputs'

    const getParamValues = (inputsObj: ICommonObject) => {
        for (const config in overrideConfig) {
            // If overrideConfig[key] is object
            if (overrideConfig[config] && typeof overrideConfig[config] === 'object') {
                const nodeIds = Object.keys(overrideConfig[config])
                if (nodeIds.includes(flowNodeData.id)) {
                    inputsObj[config] = overrideConfig[config][flowNodeData.id]
                    continue
                } else if (nodeIds.some((nodeId) => nodeId.includes(flowNodeData.name))) {
                    /*
                     * "systemMessagePrompt": {
                     *   "chatPromptTemplate_0": "You are an assistant" <---- continue for loop if current node is chatPromptTemplate_1
                     * }
                     */
                    continue
                }
            }

            let paramValue = inputsObj[config]
            const overrideConfigValue = overrideConfig[config]
            if (overrideConfigValue) {
                if (typeof overrideConfigValue === 'object') {
                    switch (typeof paramValue) {
                        case 'string':
                            if (paramValue.startsWith('{') && paramValue.endsWith('}')) {
                                try {
                                    paramValue = Object.assign({}, JSON.parse(paramValue), overrideConfigValue)
                                    break
                                } catch (e) {
                                    // ignore
                                }
                            }
                            paramValue = overrideConfigValue
                            break
                        case 'object':
                            paramValue = Object.assign({}, paramValue, overrideConfigValue)
                            break
                        default:
                            paramValue = overrideConfigValue
                            break
                    }
                } else {
                    paramValue = overrideConfigValue
                }
            }
            // Check if boolean
            if (paramValue === 'true') paramValue = true
            else if (paramValue === 'false') paramValue = false
            inputsObj[config] = paramValue
        }
    }

    const inputsObj = flowNodeData[types] ?? {}

    getParamValues(inputsObj)

    return flowNodeData
}

ループは呼び出し元が送ったすべてのキーを読みます。キーが javascriptFunction のとき、最後の代入がノードの JavaScript を呼び出し元の文字列に置き換えます。フローは保存されたチャットフローから構築され、上書きはメモリ上のノードデータに適用され、ノードは攻撃者のコードで初期化されます。チャットフローには何も書き戻されないため、保存された定義は無害に見えます。

Custom JS Function ノードはその文字列を非同期関数で包み、vm2 の NodeVM で実行します。次は Flowise 1.8.2 のノードのソースからの引用です。

const nodeVMOptions = {
    console: 'inherit',
    sandbox,
    require: {
        external: { modules: deps },
        builtin: builtinDeps
    }
} as any

const vm = new NodeVM(nodeVMOptions)
const response = await vm.run(`module.exports = async function() {${javascriptFunction}}()`, __dirname)

組み込みの許可リストには http、net、path などのモジュールが含まれますが、child_process は含まれません。それでもベンダーのアドバイザリは、この機能の影響としてサンドボックス脱出を挙げています。Era の再現では、ペイロードが child_process.execSync() を通じてシェルコマンドを実行しました。vm2 は敵対的な JavaScript に対するセキュリティ境界ではありません。脱出が相次いだため、保守担当者は 2023 年に開発を終了しました。

どのように悪用されますか?

攻撃者は通常の推論リクエストとしてエクスプロイトを送るため、保存されたチャットフローに悪意のあるコードが含まれる必要はありません。リクエスト本文には無害な質問と、実行する段階を javascriptFunction キーに入れた overrideConfig オブジェクトが含まれます。

{
  "question": "hello",
  "overrideConfig": {
    "javascriptFunction": "<JavaScript that returns the command output>"
  }
}

Era がハニーポットの通信から再現した手順は次のとおりです。

  1. インスタンスに到達し、アプリケーション認証が無効な場合は Custom JS Function ノードを含むチャットフローを使用または作成します。フレームワークのフローは ghsa-5cph-wvm9-45gj-poc という名前でした。
  2. POST /api/v1/prediction/<chatflow-id> にこのリクエスト本文を送り、質問には hello を使います。
  3. サーバーはノードの初期化前に、javascriptFunction 入力へ上書きを適用します。
  4. ノードは呼び出し元の JavaScript を vm2 サンドボックスで実行します。その段階がサンドボックスを脱出し、child_process.execSync() に到達します。
  5. コマンドの出力は推論レスポンスとして返ります。フレームワークは約 3.5 秒後に次のコマンドを再び hello として送り、このサイクルを繰り返します。
  6. 以降の段階では、ホストの列挙、環境変数と認証情報ファイルの読み取り、クラウドメタデータへの問い合わせ、Docker ソケットの確認、永続化とメモリのみのペイロードの準備を行います。

Era は、2026 年 7 月から 10 月までの 2 か月半に、4 つのリージョンにある 7 台の Flowise 1.8.2 ハニーポットに対して 4,972 件のメッセージを数えました。記録された送信元アドレスは TOR 出口ノード 185.246.188[.]74 でした。

修正はキャンペーン開始の 20 か月前、2024 年 11 月から利用可能でした。この差が要点です。2.1.4 の更新を適用しなかった配備は、キャンペーン中ずっと悪用可能なままでした。

2024 年 11 月の 2.1.4 修正から 2026 年の Greeter 攻撃、Era の報告までの年表
図 2: 修正は Greeter 攻撃の 20 か月前、2024 年 11 月に公開されました。出典: Flowise、VulnCheck、Era Security、2026 年 11 月 8 日確認

攻撃の流れは?

1 つの推論リクエストが攻撃者の JavaScript を運び、サーバーが許可リストなしでそれをノードに代入し、コードがサンドボックスを脱出して Flowise ユーザーとしてコマンドを実行します。

flowchart LR A["POST /api/v1/prediction
overrideConfig.javascriptFunction 付き"] --> B["replaceInputsWithConfig が
ノード入力へ上書きを適用
許可リストなし"] B --> C["Custom JS Function ノードが
呼び出し元の JavaScript を
vm2 内で実行"] C --> D["vm2 サンドボックス脱出"] D --> E["child_process.execSync が
Flowise ユーザーとして実行"] E --> F["偵察、.env と SSH 鍵、
クラウドメタデータの認証情報"] F --> G["永続化とメモリのみの
ペイロード準備"]

攻撃者に何ができますか?

推論 API に到達した攻撃者は、Flowise プロセスのユーザーとしてコマンドを実行し、そのプロセスが到達できるすべての秘密を読めます。Era のハニーポットの証拠は次のとおりです。

  • サービスアカウントとしてのコマンド実行。Era のハニーポットではプロセスが root で無制限の sudo を持っていましたが、これは配備の選択であり、脆弱性の性質ではありません。
  • ホストの偵察: 身元、カーネル、ディストリビューション、プロセス、待ち受けポート、ルート、環境、コンテナ識別子、Linux ケイパビリティ。
  • 認証情報の発見: .env ファイル、SSH 秘密鍵と authorized_keys、TLS クライアント証明書、SQL と SQLite ファイル、/root/.flowise/encryption.key にある Flowise の暗号化キー。
  • インスタンスメタデータサービス経由のクラウド認証情報の窃取と、ワークロードのクラウド ID に許可された操作の実行。
  • マウントされた Docker ソケットの利用。ホストや他のコンテナの制御につながる可能性があります。
  • cron と systemd ユニットによる永続化、および memfd_create() によるメモリからのペイロード実行の準備。

条件は「影響を受けますか?」に示したとおりです。2.1.4 より前のバージョン、到達可能な推論 API、Custom JS Function ノードを含むチャットフローが必要です。その後の影響は、プロセスのユーザー、マウントされたボリューム、Docker ソケット、ワークロードに付与されたクラウド ID によって変わります。Era の報告には本番の Flowise 配備に対する成功した侵害は掲載されていません。悪用の証拠はハニーポットから得られたものです。

修正が機能する理由

修正により、上書きはチャットフローごと、ノードパラメータごとにオプトインになり、運用者が有効にしない限りリクエストが javascriptFunction を置き換えられなくなりました。Flowise 2.1.4 は getAPIOverrideConfig() を追加し、チャットフローの API 設定を読みます。

export const getAPIOverrideConfig = (chatflow: IChatFlow) => {
    try {
        const apiConfig = chatflow.apiConfig ? JSON.parse(chatflow.apiConfig) : {}
        const nodeOverrides = apiConfig.overrideConfig && apiConfig.overrideConfig.nodes ? apiConfig.overrideConfig.nodes : {}
        const variableOverrides = apiConfig.overrideConfig && apiConfig.overrideConfig.variables ? apiConfig.overrideConfig.variables : []
        const apiOverrideStatus = apiConfig.overrideConfig && apiConfig.overrideConfig.status ? apiConfig.overrideConfig.status : false

        return { nodeOverrides, variableOverrides, apiOverrideStatus }
    } catch (error) {
        return { nodeOverrides: {}, variableOverrides: [], apiOverrideStatus: false }
    }
}

replaceInputsWithConfig() はノードごとの許可リストを受け取り、入力に書き込む前に確認します。

const isParameterEnabled = (nodeType: string, paramName: string): boolean => {
    if (!nodeOverrides[nodeType]) return false
    const parameter = nodeOverrides[nodeType].find((param: any) => param.name === paramName)
    return parameter?.enabled ?? false
}

// ...
if (!isParameterEnabled(flowNodeData.label, config)) {
    continue
}

上書きには 2 つの同意が必要になりました。チャットフローの overrideConfig.status が true であり、ノード種別がそのパラメータを有効として列挙している必要があります。デフォルトは false で、運用者が追加しない限り javascriptFunction は一覧にありません。同じガードは推論、エージェントグラフ、upsert の各経路に適用されます。

最初の許可リストで終わりではありませんでした。コミット c8282c97fb(2026-02-06)は、値が有効化チェックを飛ばせる FILE-STORAGE:: の例外を削除し、MCP ツールが拒否する環境変数に NODE_OPTIONS を追加しました。コミット 23b997ee5e(2026-05-07)は、生の overrideConfig オブジェクトをフローデータへ展開するのをやめました。これが呼び出し元制御のキーの 2 つ目の経路を残していました。2026-07-29 に公開された Flowise 3.1.4 は両方を含むため、実行すべきリリースです。

侵害されたかどうかを確認するには?

Flowise のリクエストログとホストでフレームワークの痕跡を探してください。チャットメッセージが hello だけでも、キャンペーンは特徴的な文字列を残します。Era は次の指標を公開しました。

  • JSON 本文に overrideConfig と javascriptFunction を含む推論リクエスト。
  • ghsa-5cph-wvm9-45gj-poc という名前のチャットフロー。
  • VP_DOCKER、VP_MEMFD、VP_W_OK、VP_INIT_OK を含むチャットメッセージ、vp-alive-[0-9a-f]{8} に一致するビーコン応答、__VP_EXIT_[0-9]+ に一致する終了報告。
  • polld-keeper-{8-hex} と varrun-watcher-{8-hex} というプロセス名。
  • /etc/cron.d/syslog-cronrun-{8-hex} の cron ファイル、または /etc/systemd/system/taskd-sysrun-{8-hex}.service の systemd ユニット。
  • 2 つの永続化コンポーネントが共有する構成ハッシュ 07f8464533b3446e918feff1ea14c4ae。
  • TOR 出口ノード 185.246.188[.]74 からの接続。

Flowise ホストと、コンテナから Docker ソケットに到達できるすべてのホストで次を実行してください。

# Flowise request logs (Docker example; adjust the container name)
docker logs <container> 2>&1 | grep -Ei 'overrideConfig|javascriptFunction|ghsa-5cph-wvm9-45gj'

# Persistence artifacts
sudo find /etc/cron.d /etc/systemd/system -maxdepth 1 \( -name 'syslog-cronrun-*' -o -name 'taskd-sysrun-*.service' \)

# Framework processes
ps -eo pid,user,args | grep -E 'polld-keeper-|varrun-watcher-'

一致は手がかりであり、証明ではありません。Flowise 自身がドキュメントと SDK で overrideConfig を使うため、フィールドに言及するリクエストは正当な場合があります。フィールドと javascriptFunction の組み合わせ、またはチャットフロー名と VP_ マーカーの組み合わせがより強い指標です。Era の証拠はハニーポットから得られたもので、本番被害者の指標は公開されていません。

年表

  • 2024-11-13: Flowise 2.1.4 がチャットフローごとの上書き許可リストとともに公開されました。
  • 2024-11-21: Flowise のアドバイザリ GHSA-5cph-wvm9-45gj が公開され、High と CVSS v4.0 8.6 が示されました。
  • 2026-02-06: コミット c8282c97fb が許可リストの FILE-STORAGE:: 回避を削除しました。
  • 2026-05-07: コミット 23b997ee5e が生の overrideConfig オブジェクトのフローデータへの展開をやめました。
  • 2026-06-20: VulnCheck が CVE-2024-58351 を CVSS v3.1 9.8 とともに公開しました。
  • 2026-11-03: Era が Greeter フレームワークの分析を公開しました。ハニーポットは 2026 年 7 月から 10 月にかけて 4,972 件の推論リクエストを記録しました。
  • 2026-11-08: この記事を公開しました。

よくある質問

Flowise 2.1.4 で十分ですか?

CVE-2024-58351 には十分です。2.1.4 が、脆弱性が回避する許可リストを追加するからです。それでも 3.1.4 以降を実行してください。2026 年の 2 つのコミットが最初の許可リストの回避を塞ぎ、呼び出し元制御のキーの 2 つ目の経路を削除しました。

認証で攻撃は止まりますか?

認証だけでは止まりません。認証は未認証のケースを除きますが、チャットフローを作成できるアカウントは Custom JS Function ノードを追加して上書きを送れます。影響を受ける 1.x および 2.0.x 系ではアプリケーション認証が単一の管理者アカウントなので、パスワードが 1 つ漏えいすれば十分です。

チャットフローに Custom JS Function ノードが必要ですか?

はい。上書きは入力の値を置き換え、javascriptFunction は Custom JS Function ノードの入力です。未認証の攻撃者はそのノードを含むフローを作成できます。Era のハニーポットで観測されたフローは ghsa-5cph-wvm9-45gj-poc という名前でした。

実際の組織に対して悪用されましたか?

Era は Greeter フレームワークを自社のハニーポットに対して観測したもので、名前のある被害者に対してではありません。また、インターネットに公開された Flowise インスタンス 4,372 件と、再現した脆弱な構成に一致する認証なしの 46 件を見つけました。これは公開の証拠であり、侵害の証明ではありません。

Flowise は High、VulnCheck は Critical と評価するのはなぜですか?

Flowise のアドバイザリは High と評価され、CVSS v4.0 ベクトルは PR:H を使って攻撃者がすでに高い権限を持つと仮定し、8.6 としています。CVE 番号機関の VulnCheck は PR:N を使い、CVSS v3.1 で 9.8、CVSS v4.0 で 9.3 と評価しています。この記事の悪用経路は、アプリケーション認証が無効な場合にネットワークアクセスだけを必要とし、VulnCheck のベクトルと一致します。

今週更新できない場合はどうすればよいですか?

リバースプロキシで信頼できないクライアントからの POST /api/v1/prediction を遮断し、公開チャットフローを無効にし、それらのクライアントが到達できるすべてのフローから Custom JS Function ノードを外してください。そのうえで更新を計画し、ホストが公開されていた場合は Flowise プロセスが読める認証情報をローテーションしてください。

Ostorlab で公開された Flowise インスタンスを見つける

Ostorlab の攻撃面発見は、組織内のインターネット公開サービスを棚卸しし、Flowise を実行する公開ホストを見つけて更新を優先できるようにします。

参考資料

  • Flowise のアドバイザリ GHSA-5cph-wvm9-45gj、2024-11-21 公開、overrideConfig の影響一覧と 2.1.4 の修正: https://github.com/FlowiseAI/Flowise/security/advisories/GHSA-5cph-wvm9-45gj(2026 年 11 月 8 日確認)
  • CVE-2024-58351 レコード、2026-06-20 公開、CVSS v3.1 9.8 と v4.0 9.3、CISA ADP の SSVC ブロック: https://www.cve.org/CVERecord?id=CVE-2024-58351(2026 年 11 月 8 日確認)
  • VulnCheck のアドバイザリ「Flowise - Remote Code Execution via overrideConfig Parameter」、2026-06-20 公開: https://www.vulncheck.com/advisories/flowise-remote-code-execution-via-overrideconfig-parameter(2026 年 11 月 8 日確認)
  • Flowise 2.1.4 の修正コミット「Enable/disable variables in override configuration」、2024-11-13: https://github.com/FlowiseAI/Flowise/commit/537aa51ef8(2026 年 11 月 8 日確認)
  • Flowise の npm パッケージ、2.1.4 は 2024-11-13 公開、現在の 3.1.4 は 2026-07-29 公開: https://www.npmjs.com/package/flowise(2026 年 11 月 8 日確認)
  • Flowise のコミット c8282c97fb「Fix Paramater Override Bypass」、2026-02-06: https://github.com/FlowiseAI/Flowise/commit/c8282c97fb(2026 年 11 月 8 日確認)
  • Flowise のコミット 23b997ee5e「remove ungated overrideConfig spread」、2026-05-07: https://github.com/FlowiseAI/Flowise/commit/23b997ee5e(2026 年 11 月 8 日確認)
  • Flowise 1.8.2 の Custom JS Function ノードのソース、NodeVM ラッパー: https://github.com/FlowiseAI/Flowise/blob/5e4d640ed7/packages/components/nodes/utilities/CustomFunction/CustomFunction.ts(2026 年 11 月 8 日確認)
  • Era Security「You Had Me at Hello: Inside The Greeter, A Chinese-Language Framework Targeting AI Infrastructure」、2026-11-03、攻撃段階、公開状況の数値、指標: https://era.security/blog/greeter-flowise-ai-infrastructure-attack(2026 年 11 月 8 日確認)
  • Flowise ドキュメント「Prediction」、エンドポイント、overrideConfig フィールド、デフォルトで無効な設定上書き: https://docs.flowiseai.com/using-flowise/prediction(2026 年 11 月 8 日確認)
  • Flowise ドキュメント「Application」認証、FLOWISE_USERNAME と FLOWISE_PASSWORD 変数: https://docs.flowiseai.com/configuration/authorization/app-level(2026 年 11 月 8 日確認)
  • CISA の Known Exploited Vulnerabilities カタログ、CVE-2024-58351 を確認: https://www.cisa.gov/known-exploited-vulnerabilities-catalog(2026 年 11 月 8 日確認)