本文へスキップ
公開済みAccess Bypass

CVE-2026-13236: Drupal AI AgentsのTool・フィールド認可

Drupal AI AgentsのToolがコンテンツを読み込む際に必要なアクセス制御が十分でなかった問題です。Agent、Tool、Entity、Fieldの認可を分けて評価する必要性を示します。

公開

アドバイザリ情報
製品
Drupal AI Agents
コンポーネント
Content Entity Tool
脆弱性クラス
Access Bypass
信頼境界
AI Agent Toolが利用者の要求をDrupal Entity・Fieldの読み取りへ変換する境界。
攻撃の前提条件
影響を受けるToolがAgentで有効になっており、攻撃者がそのAgentを利用できること。
影響
必要なアクセス制御がすべて適用されないまま、コンテンツデータが返される可能性。
根本原因
Toolのコンテンツ読み込み経路で、返却対象に必要なアクセス要件が十分に適用されていなかった。
検証バージョン
SA-CONTRIB-2026-056に記載された影響範囲
影響を受けるバージョン
1.1.4未満, 1.2.0–1.2.4, 1.3.0
修正バージョン
1.1.4, 1.2.5, 1.3.1
開示ステータス
Drupal Security Teamが公開
CVE
CVE-2026-13236
JVN
JVN#20592637
ベンダーアドバイザリ
https://www.drupal.org/sa-contrib-2026-056
クレジット
Kuniyoshi Noguchi (kuninogu)

TL;DR

Drupal SA-CONTRIB-2026-056によると、 AI AgentsのToolがContent Entityを読み込む際に、必要な権限を十分に確認していません でした。悪用には、影響を受けるToolがAgentで有効に設定され、攻撃者がそのAgentへ Accessできることが必要です。

影響範囲は1.1.4未満、1.2.0–1.2.4、1.3.0です。利用Branchに応じて1.1.4、1.2.5、 1.3.1へ更新してください。Drupalの公式アドバイザリは、Kuniyoshi Noguchi (kuninogu)をReported ByFixed Byの両方へ掲載しています。

JVN#20592637は本件を不適切な認可 (CWE-863)に分類し、利用者のPasswordを取得され、Accountを乗っ取られる可能性が あると説明しています。Field単位の出力制御は、表示やPrivacyだけでなくSecurity Boundary です。

調査理由 / なぜ重要か

AI AgentはApplication dataへの間接経路を追加します。

user -> agent -> selected tool -> entity loader -> fields -> model/user output

利用者がAgentを開く権限を持っていても、特定Entityや機密Fieldを読む権限を持つとは 限りません。同様に、Agentが多数のToolを提供できても、実際に利用を許可されたToolは 一部かもしれません。「Agentを使える」を、そのToolから到達できるすべてへの包括的な 認可として扱うと、AgentがConfused Deputyになります。

これはDrupal以外でも重要です。Agent systemは、以前はUI RouteやAPIへ分割されていた Capabilityを集約します。各Tool invocationは実行主体を維持し、Data access時と出力整形時に 対象Application本来のAuthorizationを再適用する必要があります。

Trust Boundary

少なくとも四つの独立した判断があります。

  1. Agent access: この主体はAgentと対話できるか。
  2. Tool access: このAgentは対象Toolを呼び出せるか。
  3. Entity access: 実行主体は対象Entityを閲覧できるか。
  4. Field access: 実行主体はTool結果へ含める各Fieldを閲覧できるか。

Agent/Tool requestがDrupal Entity loadへ変換され、その後Serialized resultになる箇所で Trust Boundaryを越えます。元のPrincipalの権限をその処理へ維持しなければなりません。 Entityを読み込めたことは、全Fieldを返してよい証明ではありません。UIでFieldを隠す こともAuthorization checkにはなりません。

公開アドバイザリは、正確なTool名、Route、Prompt、Method、Patch hunkを特定していません。 したがって本記事は、確認済みのAuthorization classと防御上のInvariantを説明し、Exploit pathを推測して補いません。

根本原因

Drupalが公開したRoot causeの説明は簡潔です。ToolがContent Entityを読み込む際に、Moduleが 必要なPermissionを十分に確認していませんでした。JVNはCWE-863(不適切な認可)として います。

少なくともContent load pathで、返却Dataに必要なAccess decisionのすべてを維持・適用できて いませんでした。JVNがPassword disclosureの可能性を示しているため、完全なRegression strategyにはEntity全体だけでなく、機密Field accessのTestが必要です。

誤った認可の含意は次のように表せます。

can_use_agent = true
does NOT imply can_use_every_tool
does NOT imply can_view_every_entity
does NOT imply can_view_every_field

実装上のErrorがEntity check不足、Field check不足、誤ったActing account、またはその組合せ だったかは、参照した公開アドバイザリに関数レベルで記載されていません。本記事でも、 それ以上に狭いCode-levelの原因を断定しません。

Safe reproducer

Synthetic dataを用いたLocalまたは隔離済みDrupal環境だけで実施します。実在利用者の Passwordを使ったり、Production AgentへSecretの取得を指示したりしてはいけません。

  1. 環境のBranchに対応する修正版1.1.4、1.2.5、1.3.1のいずれかを導入する。
  2. Test userが明示的に閲覧を拒否されるFieldへCANARY-NOT-A-REAL-SECRET等を入れた Synthetic EntityまたはTest accountを作る。
  3. Test Agentは利用できるが、通常のDrupal経路では保護EntityまたはFieldを閲覧できない 最小権限Userを作る。
  4. Agentでは必要なTest Toolだけを有効にし、Synthetic recordだけを対象に呼び出す。
  5. Toolが処理を拒否するか保護Fieldを除外し、CanaryがModel context・出力へ入らず、拒否が Logへ記録されることを確認する。
  6. 不足Permissionを付与して再実行する。認可後は値が返ることを確認し、Toolの故障ではなく Authorizationを検証できたことを示す。
  7. LabのRetention policyに従い、Synthetic record、Conversation、Test accountを削除する。

この方法なら製品固有Prompt、Route、実在Secretを公開せず、修正版のSecurity propertyを 検証できます。過去のExposureは、旧ProductionをExploitするのではなくVersion inventoryで 判断します。

修正差分の評価

Moduleには複数の対応Branchがあるため、Drupalは1.1.4、1.2.5、1.3.1の三つを修正版として 掲載しています。公開アドバイザリはReporterを含む複数のFix contributorを掲載していますが、 行単位のSecurity patch解説は公開していません。そのため、観測可能なAuthorization結果を 中心に評価します。

完全な修正では、次を満たす必要があります。

  • Default・Ambient・特権Service identityではなく、実際のActing principalでAccessを評価する。
  • Agentで利用を設定していないToolを拒否する。
  • Contentを読み込み・Serializeする前にEntity accessを強制する。
  • Computed fieldやReference先を含む、返却する各FieldのAccessを強制する。
  • Authorization/cache metadataを結果へ維持し、あるUser向け結果が別Userへ再利用されない。
  • IdentityまたはAccess情報が欠ける場合はfail closedにする。
  • 拒否した値を最終Chat responseだけでなく、Model context、Log、Trace、Error messageにも 含めない。

最後の点は重要です。SecretがModel promptへ入った後で表示回答だけをFilterしても、Model providerやObservability pipelineへのDisclosureは取り消せません。

回帰テスト

「Administrator」と「Anonymous」だけでなく、Authorization matrixを使います。

主体の状態AgentToolEntity機密Field期待結果
Agent権限なしDenyAnyAnyAnyTool callなし
Agent許可AllowDisabledAnyAnyTool選択・実行を拒否
Agent・Tool許可AllowAllowDenyAnyEntityを読込・返却しない
Entity許可、Field拒否AllowAllowAllowDenyFieldを除外し、拒否を記録
全Permission許可AllowAllowAllowAllow認可済みDataを返却
Queue/Background runでIdentity不明UnknownAnyAnyAnyFail closed

Reference entity、Revision、Translation、Computed field、Cached responseでもMatrixを繰り返し ます。すべての拒否CaseでCanaryがLLM request body、Tracing system、Exception log、Conversation historyに存在しないこともAssertします。

Detection

必要なTelemetry

Tool callごとにCorrelation/Run ID、Acting user ID、Agent ID、Tool ID、Entity type/ID、要求Field、 返却Field、Entity/FieldのAuthorization結果を記録します。Field valueやSecretを含むPromptは 記録しません。Drupalの標準LogだけではContextが不足する場合があるため、Tool Boundaryで 明示的なAudit eventが必要です。

Signal強度の高いInvariantは次です。

returned_fields INTERSECT denied_fields MUST equal empty_set

Audit eventで件数を正規化している場合、次の例示SPLで違反を検索できます。IndexとField名は 実装済みSchemaへ置き換えてください。

index=YOUR_DRUPAL_INDEX event_type=ai_agent_tool_result
| where returned_field_count > 0 AND denied_field_count > 0
| stats count values(entity_type) as entity_types
        values(tool_id) as tools values(run_id) as run_ids
  by user_id agent_id
| sort - count

Account/User entityへのAccess、一つのAgent sessionからの大量Entity read、同じUserが通常Route では到達できないTool実行、Model gateway・DLP telemetry内の機密Canary IDも調べます。上記 QueryはApplicationがAuthorization-aware eventを出力した後に有効な例であり、Drupal Defaultの Field名を示すものではありません。

Incident Response

  1. Logと設定を保全しながら、影響Toolを無効化するか影響AgentへのAccessを制限する。
  2. 全Drupal instanceのModule versionとAgent-to-Tool設定を記録する。
  3. Drupal log、Agent conversation、Tool-call audit event、Model gateway metadata、Reverse-proxy log、関連Database audit recordを保全する。
  4. Exposure windowを特定し、関係したPrincipal、Agent、Tool、Entity、Fieldを列挙する。記録が 許す範囲で、各Readを当時のPrincipalのAuthorizationと照合する。
  5. JVNがPassword disclosureの可能性を示しているため、返却された可能性のあるCredentialを 強制Reset/Rotationし、Sessionを失効して、その後のAccount activityを調査する。他のSecretも Scopeに応じてRotationする。
  6. 対応Branchの修正版へ更新し、Authorization-sensitive cacheを無効化して、Tool再有効化前に Regression matrixを実行する。
  7. 外部Model・Tracing providerへ送られたDataを確認し、契約上必要な通知・削除手続を行う。

機密Tool outputをIncident ticketへ複製しないでください。Raw valueが不要な場合は、Hash、ID、 Access metadataを保全します。

Disclosure Timeline

  • 報告日: 参照した公開アドバイザリには記載されていません。
  • 2026-06-24: DrupalがSA-CONTRIB-2026-056を公開し、1.1.4、1.2.5、1.3.1を修正版として 掲載。Kuniyoshi Noguchi(kuninogu)をReporter・Fix contributorの両方へ掲載。
  • 2026-07-21: JVNがJVN#20592637を公開し、開発者とIPAへの報告者としてKuniyoshi Noguchi(@KuniNogu)を掲載。
  • 非公開の調整・Patch review日: 参照した公開アドバイザリには記載されていません。

一次情報