CVE-2026-108111 および CVE-2026-108112: ruoyi-ai 3.0.0 ~ 3.1.0 におけるワークフロー検索および削除での認証チェックの欠如 脆弱性概要 Ruoyi AI は モジュール内でワークフロービルダーを提供しています。このモジュールは3つのワークフロー検索エンドポイントを公開しています。そのうち2つは所有権チェックを適切に実行しています。 はクエリ範囲を呼び出しユーザーに限定し、 は公開タグ付けされたワークフローのみを返します。一方、3つ目のエンドポイントである一般的な は、有効フラグと論理削除フラグのみでフィルタリングされ、所有者や可視性に関する制約は一切適用されません。認証済みの非管理ユーザーは同一テナント内からこのエンドポイントを呼び出すことができ、他のユーザーのプライベートなワークフロー(ワークフローUUIDおよびノードとエッジの完全な構成を含む)を取得できます(CVE-2026-108111)。 返されたUUIDは、次の認証チェック欠落箇所で使用されます。 は、呼び出し元が提供したUUIDを用いてワークフローを削除フラグ付きでマークしますが、詳細エンドポイントで使用されている所有者スコープ権限ヘルパーを介してレコードを読み込まず、権限検証を行いません。これにより、同じ非所有者ユーザーが他のユーザーのワークフローを論理削除できるようになります(CVE-2026-108112)。これら2つの欠陥は独立しており、一方はデータの漏洩、もう一方はデータの破損をもたらすため、それぞれ独立したCVE識別子が付与されました。両方のエンドポイントには有効なセッションおよび一致する ヘッダーが必要なため、これは匿名アクセスではなく、認証済みかつ同一テナント内のアクセスです。 影響範囲 CVE-2026-108111: 認証済みの非管理テナントユーザーが、他のユーザーのプライベートなワークフロー定義、およびノードとエッジの構成を列挙して読み取ることができます。製品の実装方法によっては、これらの定義にプライベートプロンプト、内部処理ロジック、または統合詳細情報が含まれている可能性があります。 CVE-2026-108112: 認証済みの非管理テナントユーザーが、所有者の同意なく、他のユーザーのワークフローを論理削除し、所有者のビューからそのワークフローを削除できます。 修正方策 CVE-2026-108111: における エンドポイントは、 の オーバーロードを呼び出しますが、このオーバーロードは および 列のみでフィルタリングします。呼び出し元のIDが追加されることはなく、公開フラグも必要とされません。 CVE-2026-108112: エンドポイントは、呼び出し元が提供したUUIDを用いてサービス更新を呼び出し、 を 1 に設定します。これは、詳細エンドポイントで使用されている所有者スコープ権限ヘルパーを介してレコードを読み込むことなく、権限検証を行いません。一般的な詳細エンドポイント は を呼び出し、非所有者を適切に拒否しますが、削除エンドポイントはそうではありません。この非対称性が根本的なバグであり、クリーンビルド環境におけるネガティブコントロールとして機能します。 POCコード ```sql INSERT INTO t_workflow (uuid, title, user_id, is_public, is_enable, remark, is_deleted, tenant_id) VALUES ('c0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0de