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

ディープダイブ

ディープダイブ

Drupal Commerce アクセス制御バイパス、野外で悪用中(CVE-2026-118539)

Drupal Commerce の 2.41 と 3.3.13 未満は、権限の限られたユーザーが JSON:API で他販売者のバリエーションやクーポンを横取り可能。悪用中。

要点

  • Drupal Commerce Core は、商品、バリエーション、クーポン、プロモーションを所有権の境界を越えてつなぐエンティティフィールドを保護していません。権限の限られたユーザーは、JSON:API や REST を通じて他の販売者のバリエーションを横取りしたり、他のプロモーションのクーポンを関連付けたりできます。顧客も自分のカートの状態や合計など制限対象フィールドを変更できました。
  • Drupal はこの欠陥を自前の尺度で Highly critical、25 点中 21 点と評価し、野外で積極的に悪用されていると述べています。アドバイザリは攻撃者も規模も指標も明かしません。CVE-2026-118539 は 2026-10-30 時点で CVSS スコアを持ちません。
  • 2.41 未満のすべての Commerce Core と、3.0.0 から 3.3.12 までが影響を受けます。2.x 系はこの修正前に 2024 年 8 月以降リリースがありませんでした。
  • Commerce Core 3.3.13 へ、旧系統なら 2.41 へ更新し、アドバイザリの指示どおり既存の注文に不整合がないか監査してください。公開資料が支える監査の観点は「侵害されたか確認するには」を参照してください。

影響を受けるか?

以下すべてが成り立つとき、影響を受けます。

  • Commerce Core モジュールが 2.41 未満、または 3.0.0 から 3.3.12 までのバージョンでインストールされていること。
  • 店舗の完全な管理者以外のアカウントが commerce エンティティに書き込めること。自分のカートを更新する顧客や、自分の商品の更新、バリエーションの管理、自分のプロモーションの更新などの commerce 権限を持つアカウントです。この欠陥はそのようなアカウントによるアクセス制御バイパスです。
  • JSON:API または REST API へのアクセスが存在すること。修正のテストはすべての乗っ取り経路にこれを使います。JSON:API は Drupal コアに同梱されています。

顧客には commerce 権限は不要です。修正前は、自分のカートの更新権限を持つ顧客が、JSON:API や REST 経由で state、total_price、adjustments、unit_price、title など注文と注文明細の制限対象フィールドを変更でき、そのカートの注文管理ルートにも到達できました。販売者間の乗っ取り経路には、限られた commerce 権限を持つアカウントが必要です。未公開商品のバリエーションなど一部のバリエーションを閲覧できないアカウントも、JSON:API コレクションのフィルタからその存在を知ることができました。

ブランチ 影響バージョン 修正バージョン
Commerce Core 3.x 3.0.0 から 3.3.12 3.3.13(2026-10-28)
Commerce Core 2.x 以前 2.41 未満のすべて 8.x-2.41(2026-10-28)

両方の修正は同じ日に公開されました。2.x 系の前回リリース 8.x-2.40 は 2024-08-22 のもので、この系統を使うサイトは 2 年以上更新から離れていました。

サイトで動くものを確認してください。

# Composer-installed sites: the resolved version in the lock file
grep -A1 '"name": "drupal/commerce"' composer.lock | grep version

# Or ask Composer directly
composer show drupal/commerce 2>/dev/null | grep ^versions

# Without Composer: the module's .info.yml carries the version when
# packaged from drupal.org
grep -r "version:" web/modules/contrib/commerce/*.info.yml 2>/dev/null

修正方法

  1. 通常の Drupal ワークフローどおり Composer で:composer require 'drupal/commerce:^3.3.13' --with-all-dependencies、2.x 系なら composer require 'drupal/commerce:^2.41' --with-all-dependencies。
  2. コード変更後のサイトの更新手順を実行し、キャッシュをクリアします:drush cr。
  3. モジュールへの独自パッチを再適用します。両方のブランチが動いたためです。
  4. 下記の確認項目で、アドバイザリの指示どおり既存の注文を監査します。

設定による回避策は存在しません。アドバイザリは何も挙げておらず、修正のテスト自身が、バイパス経路は新しいフィールド単位の検査が入って初めて閉じることを示しています。

根本原因は何か?

Commerce のエンティティにはエンティティ単位のアクセス制御はありましたが、フィールド単位はありませんでした。そのため、ある販売者のエンティティを別の販売者のものへつなぐ参照フィールドを、自分のエンティティに触れるすべてのアカウントが編集できました。

Commerce Core は商品、バリエーション、プロモーション、クーポンで財やサービスを販売し、それぞれが独自の権限を持ちます。「update own commerce_product」を持つアカウントは自分の商品を編集できます。3.3.13 の diff が示すのは、そのようなアカウントが、所有権を越える参照フィールド(商品のバリエーション一覧、クーポンの所属プロモーション、プロモーションが参照するクーポン、サイト全体の挙動を変える店舗フラグ)の編集からも止められなかったことです。

修正は各エンティティ型に restricted_fields プロパティを導入し、新しいアクセス制御ハンドラで検査します。3.3.13 の diff から、バリエーションのハンドラです。

// modules/product/src/ProductVariationAccessControlHandler.php
$restricted_fields = $this->entityType->get('restricted_fields') ?? [];
if ($operation == 'edit' && in_array($field_definition->getName(), $restricted_fields, TRUE)) {
  $result = AccessResult::allowedIfHasPermission($account, $this->entityType->getAdminPermission());
  /** @var \Drupal\commerce_product\Entity\ProductVariationInterface|null $variation */
  $variation = $items?->getEntity();
  if ($result->isAllowed() || !$variation?->isNew()) {
    return $result;
  }
  // Users who can create variations can set these fields on new variations
  // (e.g. through JSON:API or REST), as on the variation add form, which
  // allows adding variations to any product.
  return $result->orIf(AccessResult::allowedIfHasPermission($account, "manage {$variation->bundle()} commerce_product_variation"));
}

return parent::checkFieldAccess($operation, $field_definition, $account, $items);

制限対象フィールドには次のものが含まれます。

  • バリエーション: product_id。
  • クーポン: promotion_id。
  • プロモーション: coupons。
  • 店舗: is_default。
  • 注文と注文明細: 所有権・金額・状態を担うフィールド。uid、store_id、state、order_items、total_price、adjustments、unit_price、title、purchased_entity など。さらに注文の coupons、cart、checkout_flow、checkout_step、payment_gateway、payment_method。
  • 支払い方法: ゲートウェイ、所有者、リモート ID、カードのフィールド。

これらの編集には管理者権限、ハンドラが認める場合は全体更新または注文タイプ別の更新権限、新規バリエーションに限り追加フォーム自体が使う管理権限が必要です。

同じ diff は、参照が開いていた削除経路も閉じます。Promotion::postDelete() は削除されたエンティティに一致するプロモーションのクーポンだけを削除するようになり、「Coupons belonging to other promotions might be referenced (e.g. through JSON:API), those must not be deleted」というコメントが付きます。商品側の対応は商品自身のバリエーションだけを削除します。

複数のルートにも権限検査が欠けていました。顧客は自分のカートの更新権限を持つため、注文アクセスしか検査していなかった /admin/ 配下のすべての注文管理ルート(entity.commerce_order.manage_coupons_form、注文のフォームモードルート、注文明細のルートを含む)が「access commerce administration pages」を要求するようになりました。また、クーポンにはクエリアクセスの制御ハンドラがまったくなく、エンティティのオートコンプリートルートは到達できる全アカウントにすべてのクーポンコードを列挙していました。新しいセレクションプラグインがこの列挙を「administer commerce_promotion」または「update any commerce_promotion」を持つアカウントに限定します。

どのように悪用されるか?

公開されたエクスプロイトコードはありません。修正自身の機能テストが、以前は成功し修正後に失敗する正確なリクエストを文書化しています。

  1. 自分の商品を作成する権限を持つユーザーが、他の商品のバリエーションを参照する商品を JSON:API の POST で作成します。修正前はバリエーションの所有権が新商品へ移りました。修正後はリクエストが 422 で「belongs to another product」と失敗します。
  2. プロモーションの所有者が promotion_id リレーションを変える JSON:API の PATCH で、自分のクーポンの 1 つを別のプロモーションへ移します。修正前は移動しました。修正後は 403 です。
  3. オートコンプリートルートに到達できた全アカウントが、管理できないプロモーションのものを含むクーポンコードを結果で受け取っていました。
  4. JSON:API のコレクションクエリは、未公開商品のバリエーションを含む、閲覧できないバリエーションにも一致し、それらを省略済み(omitted)として列挙したため、フィルタが一致したことが露見していました。

野外での悪用は Drupal の表明です。攻撃者、送られたリクエスト、標的サイトを名指す公開記事はなく、アドバイザリは指標を何も示していません。

攻撃の流れは?

一文で述べると、権限の限られたアカウントが JSON:API や REST で参照フィールドを編集し、他の販売者のバリエーションや他のプロモーションのクーポンを自分の管理するエンティティへ関連付けると、プラットフォームが所有権ごと移動させます。

flowchart LR A["限られた commerce 権限の
アカウント"] --> B["JSON:API または REST の
書き込みリクエスト"] B --> C["参照フィールドの編集:
バリエーション、クーポン、
promotion_id"] C --> D["フィールド単位の検査なし:
リクエスト受理"] D --> E["他販売者のバリエーションや
他人のクーポンが攻撃者の
エンティティに関連付けられる"] E --> F["販売者への
金銭的影響"] G["オートコンプリートルート:
クーポンコードが
全呼び出し元に列挙"] --> D

攻撃者に何ができるか?

限られた commerce 権限のアカウントで、攻撃者は他の販売者の商品バリエーションを自分の管理するエンティティへ移動し、クーポンをプロモーション間で移動し、自分に向けられたものでないクーポンコードを列挙できます。修正前は、細工したプロモーションの削除が、他のプロモーションに属するクーポンを削除していました。Drupal は影響を「販売者に金銭的影響を与えうる」アクセス制御バイパスと要約しています。

条件は、そのカートの注文フィールドを改ざんするにはカートを持つ顧客、販売者間の乗っ取りには何らかの commerce 権限を持つアカウント、そして API アクセスです。クエリ修正が示すとおり、閲覧権限のないアカウントも隠れたバリエーションの存在を知ることができました。

アドバイザリの悪用表明が唯一の公開証拠です。「野外で積極的に悪用」以上の何も名指ししないため、影響バージョンで複数販売者または複数ロールのアカウントを持つサイトは、日時不明のまま暴露されていると扱い、指示どおり監査してください。

なぜ修正は機能するか?

修正は欠けていた層を追加します。所有権の境界を越えるまさにそのフィールドへのフィールド単位のアクセス制御で、参照が書き込まれる前に動くアクセス制御ハンドラによって強制されます。型はどのエンティティでも同じです。エンティティ型が制限フィールドを宣言し、checkFieldAccess() はアカウントが管理者権限、またはエンティティ型によっては全体更新や注文タイプ別の更新権限を持たない限り編集を拒否します。

3 つの随伴変更が残りの経路を閉じます。

  • CouponSelection::getReferenceableEntities() はプロモーションを管理できないアカウントに空リストを返し、オートコンプリートルートはもうコードを漏らしません。クーポンの利用は、列挙と検証が別経路なので、そのまま動きます。
  • Promotion::postDelete() と商品側の対応は、参照エンティティを削除する前に所有権を検査します。
  • manage_coupons_form を含む注文管理ルートが権限要件を得ます。

修正はテストが覆う経路について完全です。バリエーション乗っ取り、クーポン移動、クーポン列挙、カート・注文明細・支払い方法の制限対象フィールドへの顧客による編集、削除の副作用、そして管理ルートです。

独自の参照フィールドを追加するコントリビュートモジュールは、それを自分で保護する必要があります。restricted_fields の仕組みは拡張可能で、モジュールは hook_entity_type_build() 経由でフィールドを登録します。修正自身も注文のクーポンフィールドにこのフックを使っています。サイトで動くモジュールを確認してください。

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

アドバイザリの指示は 1 つだけです。注文の不整合を監査してください。指標、リクエストの形、攻撃者の詳細は何も公開されていないため、監査はデータモデルから行います。

  • バリエーションの作成者とは別のアカウントが所有する商品へ product_id が変わったバリエーションを列挙します。所有権の反転が乗っ取りの署名です。
  • 発行元のプロモーションと異なる promotion_id を持つクーポンと、一度も割り当てられたことのないクーポンが増えたプロモーションを列挙します。
  • 適用されたプロモーションに先行または逸脱したクーポン利用と、無関係なプロモーションのクーポンが適用された注文を探します。
  • 限られた権限のアカウントから commerce エンティティへの JSON:API と REST の書き込みと、クーポンを返したエンティティオートコンプリートのリクエストをアクセスログで確認します。
  • プロモーション削除が、他のプロモーションにまだ属するクーポンを消していないか確認します。

アクセスログがコード側より重要です。失敗した試みは、リクエストがフィールドに達した時点で API ログに 403 か 422 を残し、影響バージョンでの乗っ取り成功は 2xx(200、JSON:API の作成なら 201)を残します。

年表

  • 2024-08-22: Commerce Core 8.x-2.40 がリリースされます。この修正前の 2.x 系最後のバージョンです。
  • 2026-10-28: Commerce Core 3.3.13 と 8.x-2.41 にアクセス制御修正がタグ付けされます。
  • 2026-10-28: Drupal が SA-CONTRIB-2026-254 を公開し、Highly critical 21/25 と評価して野外で積極的に悪用されていると述べます。
  • 2026-10-29: この時点の CISA KEV カタログにはまだ何も載っていません。フィードで確認しました。
  • 2026-10-30: Drupal CNA が CVE-2026-118539 レコードを公開します。CVSS スコアなしで、認可の欠落による強制ブラウジングを記述します。The Hacker News が同日にアドバイザリを報道します。

2.x 系の 2 年の空白から、同日の修正とアドバイザリへ。CVE-2026-118539 の公開年表。
図 1: CVE-2026-118539 の公開年表。前回の 2.x リリースから修正、アドバイザリ、CVE レコードまで。出典:Commerce の Git タグ、Drupal アドバイザリ、CVE レコード、2026 年 10 月 30 日確認

FAQ

CVSS スコアはありますか?

いいえ。2026-10-30 に公開された CVE レコードにはメトリクスがなく、アドバイザリは Drupal 自身のリスク尺度を使います。Highly critical、25 点中 21 点です。ベクトルは CVSS ではなく Drupal 独自の表記で、AC:None/A:None/CI:Some/II:Some/E:Exploit/TD:All です。E:Exploit は野外悪用の表明を反映します。

匿名の訪問者は商品を乗っ取れますか?

いいえ。商品やバリエーションの乗っ取りには、限られた commerce 権限のアカウントが必要です。ただし修正は、commerce 権限を必要としない顧客が JSON:API や REST 経由で自分のカートの状態や合計など制限対象フィールドを変更することも防ぎ、隠れたバリエーションは JSON:API コレクションに省略済みエントリとして現れなくなりました。アドバイザリはこの欠陥を販売者向けに枠付けし、監査指示は注文データを対象にしています。

管理者しかいないサイトですが、影響を受けますか?

販売者間の乗っ取り経路には晒されません。これらは commerce 権限を持ちながら管理者権限を持たないアカウントを必要とします。しかし顧客は依然リスクです。カートを持つ顧客なら誰でも、JSON:API や REST 経由でそのカートの状態、合計、明細価格などの制限対象フィールドを変更できました。今すぐ修正し、アドバイザリの指示どおり注文を監査してください。

修正で店舗の動きは変わりますか?

1 点だけ変わりえます。注文でクーポンを管理していた、管理者権限のないユーザーは、オートコンプリートから選ぶ代わりにコードを入力します。この列挙がコードを漏らしていたためです。クーポンの利用そのものは変わりません。

2.x 系は何を失っていたのですか?

2024 年 8 月以降のすべてです。この修正は同じアクセス制御層をそこに適用します。2.41 タグは古いコード経路向けのフィールド制限を持ち、更新は同じ 1 ステップの移行です。

修正まで JSON:API を無効化すべきですか?

乗っ取り面を狭め、読み取り専用モードは書き込みを完全に防ぎますが、更新の代わりにはなりません。オートコンプリートルートと削除の副作用は JSON:API を必要としませんでした。まず修正し、それから利用者が求める API を再開してください。

Ostorlab で Drupal サイトを棚卸しする

Ostorlab のアタックサーフェスディスカバリーは、インターネットに公開されたサイトとそのプラットフォームを把握し、公開されたすべての Drupal サイトを特定して、攻撃者より先にモジュールのバージョンを確認できます。

参考文献

  • Drupal セキュリティアドバイザリ SA-CONTRIB-2026-254、Commerce Core、Highly critical、2026-10-28 公開: https://www.drupal.org/sa-contrib-2026-254 (2026 年 10 月 30 日確認)
  • CVE-2026-118539 レコード、Drupal CNA、2026-10-30 公開、強制ブラウジングを許す認可の欠落: https://cveawg.mitre.org/api/cve/CVE-2026-118539 (2026 年 10 月 30 日確認)
  • Commerce Core 3.3.12 から 3.3.13 への比較、アクセス制御修正、ハンドラとテスト: https://git.drupalcode.org/project/commerce/-/compare/3.3.12...3.3.13 (2026 年 10 月 30 日確認)
  • Commerce Core 8.x-2.41 タグ、2026-10-28 作成: https://git.drupalcode.org/project/commerce/-/tags/8.x-2.41 (2026 年 10 月 30 日確認)
  • Commerce Core 8.x-2.40 タグ、2024-08-22 作成、前回の 2.x リリース: https://git.drupalcode.org/project/commerce/-/tags/8.x-2.40 (2026 年 10 月 30 日確認)
  • The Hacker News、"Hackers Actively Exploit Highly Critical Drupal Commerce Core Authorization Bypass Flaw"、2026 年 10 月 30 日: https://thehackernews.com/2026/10/hackers-actively-exploit-highly.html (2026 年 10 月 30 日確認)
  • CISA KEV カタログの JSON フィード、2026 年 10 月 30 日に CVE-2026-118539 を確認(載っていない): https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json (2026 年 10 月 30 日確認)