PluginProbe
Welcart e-Commerce / 2.12.4
Welcart e-Commerce v2.12.4
2.12.4 2.12.3 2.11.35 2.12.2 2.12.1 2.11.34 2.11.33 2.11.32 2.11.31 2.11.30 1.3.16 1.3.17 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.10 1.4.11 1.4.12 All 292 releases
← All changes | functions/hoock_func.php +100 -13 2.11.342.12.4 View file →
@@ -6,8 +6,12 @@
6 6 */
7 7
8 8 add_action( 'usces_construct', 'usces_action_acting_construct', 10 );
9 9 add_action( 'usces_after_cart_instant', 'usces_action_acting_transaction', 10 );
10 +// A3 (Layer 3 / uscesid removal): restore the shopper's cart/entry for settlement notifications
11 +// from the transaction-keyed DB store, uscesid-independently. Must run after usces_session_start()
12 +// (constructor end) and before usces_main()'s `new usces_cart()`, hence the usces_main hook.
13 +add_action( 'usces_main', 'usces_restore_acting_session_from_store', 1 );
10 14
11 15 /**
12 16 * Settlement Result Notification Processing.
13 17 * usces_construct
@@ -19,10 +23,10 @@
19 23 $rand = wp_unslash( $_POST['X-S_TORIHIKI_NO'] );
20 24 $datas = array();
21 25 /* 決済成功の時のみセッション復帰 */
22 26 if ( 0 == $_POST['X-ERRLEVEL'] ) {
23 - $datas = usces_get_order_acting_data( $rand );
24 - $_GET['uscesid'] = $datas['sesid'];
27 + $datas = usces_get_order_acting_data( $rand );
28 + // A3: uscesid ブリッジは廃止。セッション復元は usces_restore_acting_session_from_store()(usces_main)で DBストアから実施.
25 29 if ( empty( $datas['sesid'] ) ) {
26 30 /* sesidが無い場合はファイルログのみ */
27 31 usces_log( 'remise construct : error1', 'acting_transaction.log' );
28 32 } else {
@@ -33,11 +37,11 @@
33 37
34 38 /* digitalcheck_conv */
35 39 } elseif ( isset( $_POST['SID'] ) && isset( $_POST['FUKA'] ) && isset( $_POST['CVS'] ) ) {
36 40
37 - $sid = wp_unslash( $_POST['SID'] );
38 - $datas = usces_get_order_acting_data( $sid );
39 - $_GET['uscesid'] = $datas['sesid'];
41 + $sid = wp_unslash( $_POST['SID'] );
42 + $datas = usces_get_order_acting_data( $sid );
43 + // A3: uscesid ブリッジは廃止。セッション復元は usces_restore_acting_session_from_store()(usces_main)で DBストアから実施.
40 44 if ( empty( $datas['sesid'] ) ) {
41 45 $log = array(
42 46 'acting' => 'digitalcheck',
43 47 'key' => $sid,
@@ -52,11 +56,11 @@
52 56
53 57 /* AnotherLane */
54 58 } elseif ( isset( $_REQUEST['SiteId'] ) && isset( $_REQUEST['rand'] ) ) {
55 59
56 - $rand = wp_unslash( $_REQUEST['rand'] );
57 - $datas = usces_get_order_acting_data( $rand );
58 - $_GET['uscesid'] = $datas['sesid'];
60 + $rand = wp_unslash( $_REQUEST['rand'] );
61 + $datas = usces_get_order_acting_data( $rand );
62 + // A3: uscesid ブリッジは廃止。セッション復元は usces_restore_acting_session_from_store()(usces_main)で DBストアから実施.
59 63 if ( empty( $datas['sesid'] ) ) {
60 64 $log = array(
61 65 'acting' => 'anotherlane',
62 66 'key' => $rand,
@@ -71,11 +75,13 @@
71 75
72 76 /* Veritrans */
73 77 } elseif ( isset( $_POST['orderId'] ) && isset( $_POST['merchantEncryptionKey'] ) ) {
74 78
75 - $orderid = wp_unslash( $_POST['orderId'] );
76 - $datas = usces_get_order_acting_data( $orderid );
77 - $_GET['uscesid'] = $datas['sesid'];
79 + $orderid = wp_unslash( $_POST['orderId'] );
80 + $datas = usces_get_order_acting_data( $orderid );
81 + // A3: uscesid ブリッジは廃止($_GET['uscesid'] を読む処理は撤廃済みのため代入は無意味だった)。
82 + // ベリトランス Air-Web は選択可能な決済から除外済み(settlement.class.php)のため、DBストアからの
83 + // セッション復元(usces_restore_acting_session_from_store)の対象外とする.
78 84 if ( empty( $datas['sesid'] ) ) {
79 85 $log = array(
80 86 'acting' => 'veritrans',
81 87 'key' => $orderid,
@@ -90,8 +96,83 @@
90 96 }
91 97 }
92 98
93 99 /**
100 + * 決済通知(サーバー間・ブラウザ Cookie 無し)で、確定時に保存したカート/エントリを DBストア
101 + * (usces_access)から $_SESSION へ復元する。uscesid セッション橋渡しの置き換え(Layer 3 / A3)。
102 + *
103 + * usces_session_start()(コンストラクタ末尾)より後・usces_main() の `new usces_cart()` より前に
104 + * 実行する必要があるため usces_main フックに登録する(construct では直後の @session_start() に
105 + * 上書きされてしまうため)。復元後、usces_cart 生成 → usces_after_cart_instant
106 + * (usces_action_acting_transaction)が $usces->cart->get_cart() を参照して処理する。
107 + *
108 + * 対象はサーバー間通知でセッション復元が要る remise / digitalcheck_conv / AnotherLane。
109 + *
110 + * usces_main
111 + */
112 +function usces_restore_acting_session_from_store() {
113 + $rand = '';
114 + if ( isset( $_POST['X-TRANID'] ) && ! isset( $_POST['OPT'] ) && isset( $_POST['X-S_TORIHIKI_NO'] ) ) {
115 + /* remise: 決済成功時(X-ERRLEVEL == 0)のみ復元 */
116 + if ( isset( $_POST['X-ERRLEVEL'] ) && 0 == $_POST['X-ERRLEVEL'] ) {
117 + $rand = wp_unslash( $_POST['X-S_TORIHIKI_NO'] );
118 + }
119 + } elseif ( isset( $_POST['SID'] ) && isset( $_POST['FUKA'] ) && isset( $_POST['CVS'] ) ) {
120 + /* digitalcheck_conv */
121 + $rand = wp_unslash( $_POST['SID'] );
122 + } elseif ( isset( $_REQUEST['SiteId'] ) && isset( $_REQUEST['rand'] ) ) {
123 + /* AnotherLane: 通知は $_REQUEST(GET/POST 両様)。旧 usces_action_acting_construct の
124 + * $_GET['uscesid']=$datas['sesid'] ブリッジの置き換え。KickType サーバー通知で order_processing()
125 + * がカートを読む前にここで DBストアから復元する。 */
126 + $rand = wp_unslash( $_REQUEST['rand'] );
127 + }
128 +
129 + if ( '' === $rand ) {
130 + return;
131 + }
132 +
133 + $datas = usces_get_order_acting_data( $rand );
134 + if ( empty( $datas ) || empty( $datas['order_data'] ) ) {
135 + return;
136 + }
137 +
138 + $order_data = wel_safe_maybe_unserialize( $datas['order_data'] );
139 + if ( ! is_array( $order_data ) ) {
140 + return;
141 + }
142 +
143 + if ( isset( $order_data['cart'] ) && is_array( $order_data['cart'] ) ) {
144 + /*
145 + * DBストア(usces_access)の cart は save_order_acting_data() が保存した
146 + * $usces->cart->get_cart() の「出力形式」= [ i => array( serial, post_id, sku, options,
147 + * price, unit_price, quantity, advance ) ](インデックス配列)。
148 + * 一方 $_SESSION['usces_cart'] の「内部形式」は
149 + * [ '<serial>' => array( 'price', 'unit_price', 'quant', 'advance' ) ](serial をキーにしたマップ)で、
150 + * usces_cart::get_cart()/key_unserialize() はこの内部形式を前提に読む
151 + * (キー=serial/数量キーは 'quant')。そのまま代入すると整数キー 0 が serial として
152 + * unserialize され false → array_keys(false) で致命的エラーになるため、内部形式へ変換して復元する。
153 + */
154 + $session_cart = array();
155 + foreach ( $order_data['cart'] as $item ) {
156 + if ( ! is_array( $item ) || ! isset( $item['serial'] ) ) {
157 + continue;
158 + }
159 + $session_cart[ $item['serial'] ] = array(
160 + 'price' => isset( $item['price'] ) ? $item['price'] : 0,
161 + 'unit_price' => isset( $item['unit_price'] ) ? $item['unit_price'] : 0,
162 + 'quant' => isset( $item['quantity'] ) ? $item['quantity'] : 0,
163 + 'advance' => isset( $item['advance'] ) ? $item['advance'] : '',
164 + );
165 + }
166 + $_SESSION['usces_cart'] = $session_cart;
167 + }
168 + if ( isset( $order_data['entry'] ) ) {
169 + $_SESSION['usces_entry'] = $order_data['entry'];
170 + }
171 + usces_log( 'acting session restored from DB store (uscesid-independent) : ' . $rand, 'acting_transaction.log' );
172 +}
173 +
174 +/**
94 175 * 決済結果通知の送信元IPが許可リストに含まれるか判定する。
95 176 *
96 177 * @param string $remote_addr Source IP address of the notification.
97 178 * @param array|string $allowed Allowed IP addresses / CIDR ranges.
@@ -496,9 +577,9 @@
496 577 usces_log( 'PayPal IPN transaction : ' . wp_unslash( $_REQUEST['txn_id'] ), 'acting_transaction.log' );
497 578 }
498 579 die( 'PayPal' );
499 580
500 - /* telecom edy */
581 + /* telecom edy 提供対象外のため無効化. CVE-2026-19887(PHP Object Injection)対応.
501 582 } elseif ( isset( $_REQUEST['clientip'] ) && isset( $_REQUEST['sendid'] ) && ( isset( $_REQUEST['acting'] ) && 'telecom_edy' == $_REQUEST['acting'] ) ) {
502 583 $data = array();
503 584 foreach ( $_REQUEST as $key => $value ) {
504 585 $data[ $key ] = $value;
@@ -513,9 +594,9 @@
513 594 if ( 'yes' === wp_unslash( $_REQUEST['rel'] ) && isset( $_REQUEST['option'] ) ) {
514 595 $table_meta_name = $wpdb->prefix . 'usces_order_meta';
515 596 $mquery = $wpdb->prepare( "SELECT order_id, meta_value FROM $table_meta_name WHERE meta_key = %s", wp_unslash( $_REQUEST['option'] ) );
516 597 $mvalue = $wpdb->get_row( $mquery, ARRAY_A );
517 - $value = unserialize( $mvalue['meta_value'] );
598 + $value = wel_safe_maybe_unserialize( $mvalue['meta_value'] );
518 599 $_SESSION['usces_cart'] = $value['usces_cart'];
519 600 $_SESSION['usces_entry'] = $value['usces_entry'];
520 601 $_SESSION['usces_member'] = $value['usces_member'];
521 602 $res = $usces->order_processing();
@@ -543,11 +624,17 @@
543 624 usces_save_order_acting_error( $log );
544 625 usces_log( 'telecom edy - Error 2 : ' . print_r( $data, true ), 'acting_transaction.log' );
545 626 }
546 627 die( 'SuccessOK' );
628 + */
547 629
548 630 /* telecom credit */
549 631 } elseif ( isset( $_REQUEST['clientip'] ) && isset( $_REQUEST['sendid'] ) && isset( $_REQUEST['rel'] ) ) {
632 + $acting_clientip = ( isset( $usces->options['acting_settings']['telecom']['clientip'] ) ) ? (string) $usces->options['acting_settings']['telecom']['clientip'] : '';
633 + if ( '' === $acting_clientip || (string) wp_unslash( $_REQUEST['clientip'] ) !== $acting_clientip ) {
634 + /* 設定済みクライアントIPと一致しない通知は正規のものではないため記録せず終了 */
635 + die( 'SuccessOK' );
636 + }
550 637 $data = array();
551 638 foreach ( $_REQUEST as $key => $value ) {
552 639 $data[ $key ] = $value;
553 640 }