EC-CUBE / EC-CUBE/ec-cube2

クレジット決済画面で決済確定しなかった場合、会員のポイントが異常加算されることがある不具合

Open
#303 17 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
PHP
Stars
92
Forks
97
Avg merge
4d 2h
Merged PRs (30d)
9

Description

SC_Helper_Purchase.php の public function sfUpdateOrderStatus で適切な排他処理がされていないため、以下のシナリオで、会員のポイントが異常に加算されることがあります。

登場人物

- A: 会員。商品を購入しようとする人(ポイント計算異常の対象者)
- B: EC-CUBEにアクセスしたきた一般の人
- C: Bとほぼ同時にEC-CUBEにアクセスしてきた一般の人

シナリオ

1. 1,000ポイントを既に持っている会員Aが商品をカートに入れる
2. 購入手続きで1,000ポイントを使用する
3. 決済でクレジットカードを選択する
4. クレジットカード番号入力画面に遷移する
5. クレジットカード番号を入力せずブラウザを閉じる
6. それから十分に時間が経ってからB,Cがほぼ同時にEC-CUBEにアクセスする
7. 会員Aのポイントが、元より1,000ポイント増えて2,000ポイントになる

原因

- Aが買い物をしてクレジットカード番号入力画面に遷移した時点で、Aの会員ポイントが1,000ポイント減算され、dtb_customer上Aは0ポイントとなり、一方で、dtb_orderにAの1,000ポイントが登録された状態になる
- Aがその画面で離脱したため、上記の状態が一定時間維持される
- その後、B,CがEC-CUBEにアクセスすることにより、SC_Helper_Purchase.php の public function cancelPendingOrder が呼び出され、決済途中で放棄されたAの受注関連データの回復処理が実行される(2人が同時にアクセスした場合、ほぼ同時に2回、このfunctionが実行される)
- cancelPendingOrder -> checkDbAllPendingOrder -> cancelOrder -> registerOrder -> sfUpdateOrderStatus の順でfunctionが呼び出される
- sfUpdateOrderStatus 内では、 dtb_order からAの受注情報を取得し、加減算すべきポイントを計算し、計算結果に基づき dtb_customer のAのポイントを更新(+1,000ポイント)し、dtb_orderのステータスをキャンセル済に更新する
- しかしここで適切な排他処理がされていないため、ほぼ同時に2人がアクセスしてくると、例えばBのアクセスによってdtb_orderのステータスがキャンセル済に更新される前に、Cのアクセスによるポイント更新の処理が重複して実行されてしまい、結果、Aには1,000ポイントが2回加算されることになる

以上を報告させていただきます。

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.