Changeset 3743211 for usc-e-shop
- Timestamp:
- 10/13/2026 08:01:44 AM (5 days ago)
- Location:
- usc-e-shop/trunk
- Files:
-
- 15 edited
-
classes/orderList.class.php (modified) (5 diffs)
-
classes/paymentDigitalcheck.class.php (modified) (2 diffs)
-
classes/paymentPayPalCP.class.php (modified) (4 diffs)
-
classes/paymentPaygent.class.php (modified) (2 diffs)
-
classes/paymentPaygent.module.class.php (modified) (3 diffs)
-
classes/paymentZeus.class.php (modified) (8 diffs)
-
classes/rateLimiter.class.php (modified) (7 diffs)
-
classes/usceshop.class.php (modified) (9 diffs)
-
extensions/BruteForceCountermeasures/brute_force_countermeasures.php (modified) (2 diffs)
-
extensions/VerifyMembersEmail/verify_members_email.php (modified) (1 diff)
-
functions/filters.php (modified) (4 diffs)
-
functions/hoock_func.php (modified) (7 diffs)
-
includes/default_filters.php (modified) (1 diff)
-
readme.txt (modified) (3 diffs)
-
usc-e-shop.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
usc-e-shop/trunk/classes/orderList.class.php
r3699516 r3743211 209 209 check_admin_referer( 'order_list', 'wc_nonce' ); 210 210 usces_all_change_order_reciept( $this ); 211 $this->SearchIn(); 211 212 $res = $this->GetRows(); 212 213 break; … … 215 216 check_admin_referer( 'order_list', 'wc_nonce' ); 216 217 usces_all_change_order_status( $this ); 218 $this->SearchIn(); 217 219 $res = $this->GetRows(); 218 220 break; … … 222 224 usces_all_delete_order_data( $this ); 223 225 $this->SetTotalRow(); 226 $this->SearchIn(); 224 227 $res = $this->GetRows(); 225 228 break; … … 473 476 $rows = $wpdb->get_results( $query, ARRAY_A ); 474 477 $this->selectedRow = ( $rows && is_array( $rows ) ) ? count( $rows ) : 0; 478 // 絞り込み結果の件数より開始行が後ろにある場合は先頭ページへ戻す. 479 if ( $this->startRow >= $this->selectedRow ) { 480 $this->currentPage = 1; 481 $this->startRow = 0; 482 } 475 483 if ( 'on' == $this->pageLimit ) { 476 484 $this->rows = array_slice( (array) $rows, $this->startRow, $this->maxRow ); … … 636 644 public function SearchIn() { 637 645 global $wpdb; 646 // Cookie から読み戻した SQL 断片は使わず, arr_search から毎回作り直す. 647 $this->searchSql = ''; 648 $this->searchSkuSql = ''; 638 649 switch ( $this->arr_search['column'] ) { 639 650 case 'ID': -
usc-e-shop/trunk/classes/paymentDigitalcheck.class.php
r3673344 r3743211 781 781 * ブラウザ戻りを伴う結果戻りでは呼び出さない 782 782 * 783 * @param array $data Notification data. 783 * @param array $data Notification data. 784 * @param string $acting Acting name for the error log. 784 785 * @return void 785 786 */ 786 public function acting_notice_ip_guard( $data ) {787 public function acting_notice_ip_guard( $data, $acting = 'digitalcheck_conv' ) { 787 788 $remote_addr = ( isset( $_SERVER['REMOTE_ADDR'] ) ) ? wp_unslash( $_SERVER['REMOTE_ADDR'] ) : ''; 788 789 if ( usces_acting_notice_ip_allowed( $remote_addr, self::ACTING_NOTICE_IPADDRS ) ) { … … 790 791 } 791 792 $log = array( 792 'acting' => 'digitalcheck_conv',793 'acting' => $acting, 793 794 'key' => ( isset( $data['SID'] ) ) ? $data['SID'] : '', 794 795 'result' => 'IP ADDRESS NOT ALLOWED: ' . $remote_addr, -
usc-e-shop/trunk/classes/paymentPayPalCP.class.php
r3673344 r3743211 2264 2264 2265 2265 /** 2266 * Create billing agreement. 2267 */ 2268 /** 2269 * A5 (Layer 3 / uscesid removal): reopen the shopper's shop session from its own 2270 * same-origin session cookie (USCES_KEY) instead of decoding a crafted `uscesid` GET 2271 * param through uscesdc()/session_id(). These nopriv admin-ajax handlers run under 2272 * admin-ajax.php, where usces_close_session() (admin_init) has closed the bootstrap 2273 * session, so session_status() is PHP_SESSION_NONE here. get_entry()/get_cart()/ 2274 * get_member() read $_SESSION live, so reattaching before they run restores the 2275 * shopper's cart/entry/member. Mirrors A2 (cart-monitor) / A6 (Zeus enrol). 2276 * The uk session cookie is HttpOnly but is still sent on same-origin fetch() 2277 * (default credentials: 'same-origin') and readable via $_COOKIE. 2278 * See .docs/welcart2.x/security-remediation_uscesid-layer3-a3-a6-design.md A5. 2266 * Reattach the shopper's shop session from its session cookie. 2267 * 2268 * On admin-ajax.php the bootstrap session is already closed by 2269 * usces_close_session() (admin_init), so reopen it before reading the cart. 2279 2270 */ 2280 2271 private function reattach_shop_session() { … … 2290 2281 } 2291 2282 2283 /** 2284 * Create billing agreement. 2285 */ 2292 2286 public function create_billing_agreement() { 2293 2287 global $usces; … … 2413 2407 /* Create order */ 2414 2408 $response_data = $this->api_create_order( $access_token, $bn_code, '', $tracking_id, $entry, $cart, false ); 2409 if ( isset( $response_data->id ) ) { 2410 $usces->cart->set_order_entry( array( 'paypal_cp_card_resource_id' => $response_data->id ) ); 2411 } 2415 2412 wp_send_json( $response_data ); 2416 2413 } … … 2493 2490 */ 2494 2491 public function show_order_details_card() { 2492 global $usces; 2493 2494 $this->reattach_shop_session(); 2495 2495 2496 $bn_code = self::API_BN_CODE_ACDC; 2496 2497 $tracking_id = ( isset( $_POST['tracking_id'] ) ) ? wp_unslash( $_POST['tracking_id'] ) : ''; /* rand|reference_id */ 2497 2498 $resource_id = ( isset( $_POST['resource_id'] ) ) ? wp_unslash( $_POST['resource_id'] ) : ''; 2499 2500 /* Only an order created in the current shop session can be referenced. */ 2501 $saved_resource_id = $usces->cart->get_order_entry( 'paypal_cp_card_resource_id' ); 2502 if ( '' === $resource_id || empty( $saved_resource_id ) || ! hash_equals( (string) $saved_resource_id, $resource_id ) ) { 2503 wp_send_json( array() ); 2504 } 2498 2505 2499 2506 /* Get Access Token */ -
usc-e-shop/trunk/classes/paymentPaygent.class.php
r3699516 r3743211 8195 8195 * 決済ステータス取得 8196 8196 * 8197 * 決済ログには決済ステータスと電文種別が混在して記録されているため、 8198 * 電文種別の記録を除外したうえで最新の決済ステータスを返す。 8199 * 8197 8200 * @param int $order_id Order number. 8198 8201 * @param string $trading_id Trading ID. … … 8200 8203 */ 8201 8204 private function get_payment_status( $order_id, $trading_id ) { 8202 global $wpdb;8203 8204 8205 $payment_status = ''; 8205 $latest_log = $this->get_acting_latest_log( $order_id, $trading_id, RESULT_STATUS_ALL ); 8206 if ( isset( $latest_log['status'] ) ) { 8207 $payment_status = $latest_log['status']; 8206 $log_data = $this->get_acting_log( $order_id, $trading_id, RESULT_STATUS_ALL ); 8207 foreach ( (array) $log_data as $data ) { 8208 if ( empty( $data['status'] ) ) { 8209 continue; 8210 } 8211 /* 電文種別は実行した処理の記録であって決済状況ではないため除外する. */ 8212 if ( $this->is_telegram_kind( $data['status'] ) ) { 8213 continue; 8214 } 8215 $payment_status = $data['status']; 8216 break; 8217 } 8218 /* 決済ステータスの記録が無い場合は従来どおり最新の記録を採用する. */ 8219 if ( '' === $payment_status ) { 8220 $latest_log = $this->get_acting_latest_log( $order_id, $trading_id, RESULT_STATUS_ALL ); 8221 if ( isset( $latest_log['status'] ) ) { 8222 $payment_status = $latest_log['status']; 8223 } 8208 8224 } 8209 8225 return $payment_status; 8226 } 8227 8228 /** 8229 * 電文種別判定 8230 * 8231 * 決済ログの status に記録された値が、決済ステータスではなく 8232 * 加盟店側で実行した処理の電文種別であるかを判定する。 8233 * 8234 * @param string $status Status. 8235 * @return bool 8236 */ 8237 private function is_telegram_kind( $status ) { 8238 $telegram_kinds = array( 8239 PAYGENT_CREDIT, /* 020 カード決済オーソリ */ 8240 PAYGENT_AUTH_CANCEL, /* 021 カード決済オーソリキャンセル */ 8241 PAYGENT_CARD_COMMIT, /* 022 カード決済売上 */ 8242 PAYGENT_CARD_COMMIT_CANCEL, /* 023 カード決済売上キャンセル */ 8243 PAYGENT_CARD_COMMIT_AUTH_REVISE, /* 028 カード決済補正オーソリ */ 8244 PAYGENT_CARD_COMMIT_REVISE, /* 029 カード決済補正売上 */ 8245 PAYGENT_PAIDY_AUTH_CANCEL, /* 340 Paidyオーソリキャンセル */ 8246 PAYGENT_PAIDY_CAPTURE, /* 341 Paidy売上 */ 8247 PAYGENT_PAIDY_REFUND, /* 342 Paidy返金 */ 8248 ); 8249 return in_array( (string) $status, $telegram_kinds, true ); 8210 8250 } 8211 8251 -
usc-e-shop/trunk/classes/paymentPaygent.module.class.php
r3320299 r3743211 1026 1026 public function post_request_body( $form_data ) { 1027 1027 // 通信開始. 1028 $this->init_curl(); 1028 $ret_code = $this->init_curl(); 1029 if ( true !== $ret_code ) { 1030 $this->close_curl(); 1031 return $ret_code; 1032 } 1029 1033 1030 1034 // リクエストを送信. … … 1103 1107 * 接続のための初期化処理 1104 1108 * 1105 * @return mixed 1109 * @return mixed TRUE:成功、他:エラーコード 1106 1110 */ 1107 1111 public function init_curl() { 1108 $rslt = true;1109 1110 1112 // 初期化. 1111 1113 $this->ch = curl_init( $this->url ); 1112 1113 $rslt = $rslt && curl_setopt( $this->ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0 ); 1114 $rslt = $rslt && curl_setopt( $this->ch, CURLOPT_RETURNTRANSFER, true ); 1115 $rslt = $rslt && curl_setopt( $this->ch, CURLOPT_POST, true ); 1116 $rslt = $rslt && curl_setopt( $this->ch, CURLOPT_HEADER, true ); 1117 1118 // 証明書. 1119 $rslt = $rslt && curl_setopt( $this->ch, CURLOPT_SSL_VERIFYHOST, false ); 1120 1121 // クライアント証明書. 1122 $rslt = $rslt && curl_setopt( $this->ch, CURLOPT_SSLCERT, $this->client_certificate_path ); 1123 $rslt = $rslt && curl_setopt( $this->ch, CURLOPT_SSLKEYPASSWD, $this->keystore_password ); 1124 1125 // CA証明書. 1126 $rslt = $rslt && curl_setopt( $this->ch, CURLOPT_SSL_VERIFYPEER, true ); 1127 $rslt = $rslt && curl_setopt( $this->ch, CURLOPT_CAINFO, $this->ca_certificate_path ); 1128 1129 // タイムアウト. 1130 $rslt = $rslt && curl_setopt( $this->ch, CURLOPT_TIMEOUT, $this->timeout ); 1131 1132 return $rslt; 1114 if ( false === $this->ch ) { 1115 $this->ch = null; 1116 $this->result_message = KS_CONNECT_ERROR . ': curl_init failed'; 1117 return KS_CONNECT_ERROR; 1118 } 1119 1120 $options = array( 1121 'CURLOPT_HTTP_VERSION' => CURL_HTTP_VERSION_1_0, 1122 'CURLOPT_RETURNTRANSFER' => true, 1123 'CURLOPT_POST' => true, 1124 'CURLOPT_HEADER' => true, 1125 // 証明書. 1126 'CURLOPT_SSL_VERIFYHOST' => false, 1127 // クライアント証明書. 1128 'CURLOPT_SSLCERT' => $this->client_certificate_path, 1129 'CURLOPT_SSLKEYPASSWD' => $this->keystore_password, 1130 // CA証明書. 1131 'CURLOPT_SSL_VERIFYPEER' => true, 1132 'CURLOPT_CAINFO' => $this->ca_certificate_path, 1133 // タイムアウト. 1134 'CURLOPT_TIMEOUT' => $this->timeout, 1135 ); 1136 1137 // 1つの失敗で以降の設定が飛ばされないよう、すべて個別に設定する. 1138 $failed_options = array(); 1139 foreach ( $options as $name => $value ) { 1140 if ( ! curl_setopt( $this->ch, constant( $name ), $value ) ) { 1141 $failed_options[] = $name; 1142 } 1143 } 1144 if ( empty( $failed_options ) ) { 1145 return true; 1146 } 1147 1148 // 証明書ファイルの設定に失敗した場合は証明書エラーとする. 1149 $certificate_options = array( 'CURLOPT_SSLCERT', 'CURLOPT_SSLKEYPASSWD', 'CURLOPT_CAINFO' ); 1150 if ( array_intersect( $failed_options, $certificate_options ) ) { 1151 $ret_code = CERTIFICATE_ERROR; 1152 } else { 1153 $ret_code = KS_CONNECT_ERROR; 1154 } 1155 $this->result_message = $ret_code . ': curl_setopt failed (' . implode( ', ', $failed_options ) . ')'; 1156 $this->result_message .= $this->get_certificate_file_status(); 1157 return $ret_code; 1133 1158 } 1134 1159 … … 1191 1216 $ret_code = KS_CONNECT_ERROR; 1192 1217 } 1193 $this->result_message = $ret_code . ': ' . $error_msg; 1194 1195 // 証明書ファイルの状態チェック. 1218 $this->result_message = $ret_code . ': ' . $error_msg; 1219 $this->result_message .= $this->get_certificate_file_status(); 1220 return $ret_code; 1221 } 1222 1223 /** 1224 * 証明書ファイルの状態チェック 1225 * 1226 * @return string 問題がある場合はその内容、なければ空文字 1227 */ 1228 protected function get_certificate_file_status() { 1229 $status = ''; 1196 1230 if ( ! file_exists( $this->client_certificate_path ) ) { 1197 $ this->result_message.= '(file is not exists: ' . $this->client_certificate_path . ')';1231 $status .= '(file is not exists: ' . $this->client_certificate_path . ')'; 1198 1232 } elseif ( ! is_readable( $this->client_certificate_path ) ) { 1199 $ this->result_message.= '(file is not readable: ' . $this->client_certificate_path . ')';1233 $status .= '(file is not readable: ' . $this->client_certificate_path . ')'; 1200 1234 } 1201 1235 if ( ! file_exists( $this->ca_certificate_path ) ) { 1202 $ this->result_message.= '(file is not exists: ' . $this->ca_certificate_path . ')';1236 $status .= '(file is not exists: ' . $this->ca_certificate_path . ')'; 1203 1237 } elseif ( ! is_readable( $this->ca_certificate_path ) ) { 1204 $ this->result_message.= '(file is not readable: ' . $this->ca_certificate_path . ')';1205 } 1206 return $ ret_code;1238 $status .= '(file is not readable: ' . $this->ca_certificate_path . ')'; 1239 } 1240 return $status; 1207 1241 } 1208 1242 -
usc-e-shop/trunk/classes/paymentZeus.class.php
r3673344 r3743211 4837 4837 } elseif ( 'acting_zeus_card' === $acting_flg && 1 === (int) $acting_opts['connection'] ) { 4838 4838 4839 // Use the amount from the session, not the posted value. 4840 $entry = $usces->cart->get_entry(); 4839 4841 $sendid = ( 'on' === $acting_opts['quickcharge'] && $usces->is_member_logged_in() && isset( $post_data['sendid'] ) ) ? $post_data['sendid'] : ''; 4840 4842 $sendpoint = ( isset( $post_data['sendpoint'] ) ) ? $post_data['sendpoint'] : ''; … … 4850 4852 $params['token_key'] = $post_data['token_key']; 4851 4853 } 4852 $params['money'] = $post_data['money'];4854 $params['money'] = apply_filters( 'zeus_secure_payreq_amount', usces_crform( $entry['order']['total_full_price'], false, false, 'return', false ), $entry ); 4853 4855 $params['telno'] = str_replace( '-', '', $post_data['telno'] ); 4854 4856 $params['email'] = $post_data['email']; … … 4902 4904 4903 4905 $interface = $this->get_interface( $acting_opts['conv_url'] ); 4906 // Use the amount from the session, not the posted value. 4907 $entry = $usces->cart->get_entry(); 4904 4908 4905 4909 $params = array(); 4906 4910 $params['clientip'] = $acting_opts['clientip_conv']; 4907 4911 $params['act'] = $post_data['act']; 4908 $params['money'] = $post_data['money'];4912 $params['money'] = usces_crform( $entry['order']['total_full_price'], false, false, 'return', false ); 4909 4913 $params['username'] = mb_convert_encoding( $post_data['username'], 'SJIS', 'UTF-8' ); 4910 4914 $params['telno'] = str_replace( '-', '', $post_data['telno'] ); … … 5045 5049 'tel' => $post_data['tel_mobile'], 5046 5050 'email' => trim( $entry['customer']['mailaddress1'] ), 5047 'billedAmount' => $post_data['money'],5051 'billedAmount' => usces_crform( $entry['order']['total_full_price'], false, false, 'return', false ), 5048 5052 'expand1' => '', 5049 5053 'service' => '2', … … 5132 5136 $result_data = array( 5133 5137 'acting' => 'zeus_bnpl', 5134 'money' => $post_data['money'],5138 'money' => usces_crform( $entry['order']['total_full_price'], false, false, 'return', false ), 5135 5139 'response' => $response['response'], 5136 5140 ); … … 7109 7113 check_ajax_referer( 'acting_zeus_card', '_nonce' ); 7110 7114 7111 // A6 (Layer 3 / uscesid removal):この nopriv admin-ajax は usces_close_session()(admin_init)7115 // この nopriv admin-ajax は usces_close_session()(admin_init) 7112 7116 // の後に走るため session_status() は PHP_SESSION_NONE。旧実装は JS が付けた `?uscesid=` を 7113 7117 // usces_session_start() が復号して買い物客セッションへ切替えていたが、uscesid を廃し、 7114 // 同一オリジンの USCES_KEY cookie から買い物客セッションを再開する (A2 と同一方式).7118 // 同一オリジンの USCES_KEY cookie から買い物客セッションを再開する. 7115 7119 if ( PHP_SESSION_NONE === session_status() ) { 7116 7120 $usces_options = get_option( 'usces' ); … … 7147 7151 $sendpoint = filter_input( INPUT_POST, 'sendpoint', FILTER_DEFAULT, array( 'options' => array( 'default' => '' ) ) ); 7148 7152 $_nonce = filter_input( INPUT_POST, '_nonce', FILTER_DEFAULT, array( 'options' => array( 'default' => wp_create_nonce( 'acting_zeus_card' ) ) ) ); 7149 // A6:uscesid ブリッジ廃止。3DS 戻り(TermUrl)のセッションは sendpoint(取引キー)で7153 // uscesid ブリッジ廃止。3DS 戻り(TermUrl)のセッションは sendpoint(取引キー)で 7150 7154 // acting_processing() が usces_restore_order_acting_data() 復元するため uscesid は不要. 7151 7155 … … 7451 7455 $data['token_key'] = filter_input( INPUT_POST, 'token_key' ); 7452 7456 } 7453 $data['payment']['amount'] = apply_filters( 'zeus_secure_payreq_amount', filter_input( INPUT_POST, 'money' ), $entry ); 7457 // Use the amount from the session, not the posted value. 7458 $entry = $usces->cart->get_entry(); 7459 $data['payment']['amount'] = apply_filters( 'zeus_secure_payreq_amount', usces_crform( $entry['order']['total_full_price'], false, false, 'return', false ), $entry ); 7454 7460 if ( isset( $_POST['howpay'] ) && WCUtils::is_zero( filter_input( INPUT_POST, 'howpay' ) ) ) { 7455 7461 $data['payment']['count'] = filter_input( INPUT_POST, 'div' ); -
usc-e-shop/trunk/classes/rateLimiter.class.php
r3218674 r3743211 7 7 class RateLimiter { 8 8 9 public $folder_log_path; 10 public $login_failed_log_path; 11 public $ip_blocked_path; 9 /** 10 * Log type of member login failed. 11 * 12 * @since 2.12.5 13 */ 14 const LOG_TYPE_LOGIN_FAILED = 'member_login_failed'; 15 16 /** 17 * Log type of IP addresses blocked. 18 * 19 * @since 2.12.5 20 */ 21 const LOG_TYPE_IP_BLOCKED = 'ip_addresses_blocked'; 22 12 23 public $monitoring; /* minutes */ 13 24 public $num_of_errors; … … 20 31 */ 21 32 public function __construct() { 22 23 $this->folder_log_path = USCES_WP_CONTENT_DIR . '/uploads/usces_logs/';24 $this->login_failed_log_path = $this->folder_log_path . 'member_login_failed.log';25 $this->ip_blocked_path = $this->folder_log_path . 'ip_addresses_blocked.log';26 33 27 34 // get brute force config. … … 32 39 $this->status = ( ! isset( $options['system']['brute_force']['status'] ) ) ? 0 : (int) $options['system']['brute_force']['status']; 33 40 $this->excluded_ip = ( ! isset( $options['system']['brute_force']['excluded_ip'] ) ) ? array() : $options['system']['brute_force']['excluded_ip']; 34 35 if ( $this->status ) {36 $this->initLogsFolder();37 }38 41 } 39 42 … … 51 54 } 52 55 53 $data = $this->getLoginFailedDataByIP( $ip ); 54 $ip_blocked = $this->getIpAddressesBlocked(); 55 56 if ( isset( $ip_blocked[ $ip ] ) && ( strtotime( "-{$this->rejection_time} minutes" ) < $ip_blocked[ $ip ] ) ) { 56 if ( $this->is_blocked( $ip ) ) { 57 57 $this->saveLoginFailed(); 58 58 return true; 59 59 } 60 60 61 if ( count( $data ) ) { 62 $count = 0; 63 foreach ( $data as $key => $value ) { 64 if ( strtotime( "-{$this->monitoring} minutes" ) < $key ) { 65 $count += $value; 66 } 67 } 68 if ( $count >= $this->num_of_errors ) { 69 $ip_blocked[ $ip ] = strtotime( 'now' ); 70 file_put_contents( $this->ip_blocked_path, json_encode( $ip_blocked ) ); 71 return true; 72 } 61 if ( $this->count_login_failed( $ip ) >= $this->num_of_errors ) { 62 $this->insert_log( self::LOG_TYPE_IP_BLOCKED, $ip ); 63 return true; 73 64 } 74 65 } catch ( Throwable $exception ) { … … 92 83 } 93 84 94 $content = $this->getLoginFailedData(); 95 $row = $this->getLoginFailedDataByIP( $ip ); 96 97 $row[ strtotime( 'now' ) ] = ( isset( $row[ strtotime( 'now' ) ] ) ) ? ( $row[ strtotime( 'now' ) ] + 1 ) : 1; 98 99 if ( count( $row ) > $this->num_of_errors ) { 100 unset( $row[ array_key_first( $row ) ] ); 101 } 102 $content[ $ip ] = $row; 103 file_put_contents( $this->login_failed_log_path, json_encode( $content ) ); 104 105 $number_of_login_fail = 0; 106 foreach ( $content[ $ip ] as $key => $value ) { 107 if ( strtotime( "-{$this->monitoring} minutes" ) < $key ) { 108 $number_of_login_fail++; 109 } 110 } 111 112 if ( $number_of_login_fail >= $this->num_of_errors ) { 113 $ip_blocked = $this->getIpAddressesBlocked(); 114 $ip_blocked[ $ip ] = strtotime( 'now' ); 115 file_put_contents( $this->ip_blocked_path, json_encode( $ip_blocked ) ); 85 $this->delete_expired_logs(); 86 $this->insert_log( self::LOG_TYPE_LOGIN_FAILED, $ip ); 87 88 if ( $this->count_login_failed( $ip ) >= $this->num_of_errors ) { 89 $this->insert_log( self::LOG_TYPE_IP_BLOCKED, $ip ); 116 90 117 91 $wp_query->set_403(); … … 129 103 */ 130 104 public function clear_login_failed() { 105 global $wpdb; 106 131 107 try { 132 108 if ( $this->status ) { 133 $ip = $_SERVER['REMOTE_ADDR']; 134 $content = $this->getLoginFailedData(); 135 unset( $content[ $ip ] ); 136 file_put_contents( $this->login_failed_log_path, json_encode( $content ) ); 109 $ip = $_SERVER['REMOTE_ADDR']; 110 $wpdb->query( 111 $wpdb->prepare( 112 "DELETE FROM {$wpdb->prefix}usces_log WHERE `log_type` = %s AND `log_key` = %s", 113 self::LOG_TYPE_LOGIN_FAILED, 114 $ip 115 ) 116 ); 137 117 } 138 118 } catch ( Throwable $exception ) { … … 142 122 143 123 /** 144 * Get login failed data 145 * 146 * @return array 147 */ 148 public function getLoginFailedData() { 149 if ( usces_is_reserved_file( $this->login_failed_log_path, 1 ) ) { 150 $res = json_decode( file_get_contents( $this->login_failed_log_path ), true ); 151 } else { 152 $res = array(); 153 } 154 return $res; 155 } 156 157 /** 158 * Get login failed data by IP 159 * 124 * Clear all logs of login failed and IP addresses blocked. 125 * 126 * @since 2.12.5 127 */ 128 public static function clear_all() { 129 global $wpdb; 130 131 $wpdb->query( 132 $wpdb->prepare( 133 "DELETE FROM {$wpdb->prefix}usces_log WHERE `log_type` IN ( %s, %s )", 134 self::LOG_TYPE_LOGIN_FAILED, 135 self::LOG_TYPE_IP_BLOCKED 136 ) 137 ); 138 } 139 140 /** 141 * Insert log. 142 * 143 * @since 2.12.5 144 * 145 * @param string $log_type Log type. 160 146 * @param string $ip IP Address. 161 * @return array 162 */ 163 public function getLoginFailedDataByIP( $ip ) { 164 $content = $this->getLoginFailedData(); 165 return ( isset( $content[ $ip ] ) ) ? $content[ $ip ] : array(); 166 } 167 168 /** 169 * Get IP Addresses blocked 170 * 171 * @return array 172 */ 173 public function getIpAddressesBlocked() { 174 if ( usces_is_reserved_file( $this->ip_blocked_path, 1 ) ) { 175 $res = json_decode( file_get_contents( $this->ip_blocked_path ), true ); 176 } else { 177 $res = array(); 178 } 179 return $res; 180 } 181 182 /** 183 * Init logs folder 184 */ 185 public function initLogsFolder() { 186 if ( ! is_dir( $this->folder_log_path ) ) { 187 mkdir( $this->folder_log_path, 0775 ); 188 } 147 */ 148 private function insert_log( $log_type, $ip ) { 149 global $wpdb; 150 151 $wpdb->query( 152 $wpdb->prepare( 153 "INSERT INTO {$wpdb->prefix}usces_log ( `datetime`, `log_type`, `log_key` ) VALUES ( %s, %s, %s )", 154 current_time( 'mysql' ), 155 $log_type, 156 $ip 157 ) 158 ); 159 } 160 161 /** 162 * Count login failed within the monitoring span. 163 * 164 * @since 2.12.5 165 * 166 * @param string $ip IP Address. 167 * @return int 168 */ 169 private function count_login_failed( $ip ) { 170 global $wpdb; 171 172 $count = $wpdb->get_var( 173 $wpdb->prepare( 174 "SELECT COUNT(`ID`) FROM {$wpdb->prefix}usces_log WHERE `datetime` > %s AND `log_type` = %s AND `log_key` = %s", 175 $this->get_cutoff_datetime( $this->monitoring ), 176 self::LOG_TYPE_LOGIN_FAILED, 177 $ip 178 ) 179 ); 180 return (int) $count; 181 } 182 183 /** 184 * Is the IP address blocked within the rejection time. 185 * 186 * @since 2.12.5 187 * 188 * @param string $ip IP Address. 189 * @return bool 190 */ 191 private function is_blocked( $ip ) { 192 global $wpdb; 193 194 $count = $wpdb->get_var( 195 $wpdb->prepare( 196 "SELECT COUNT(`ID`) FROM {$wpdb->prefix}usces_log WHERE `datetime` > %s AND `log_type` = %s AND `log_key` = %s", 197 $this->get_cutoff_datetime( $this->rejection_time ), 198 self::LOG_TYPE_IP_BLOCKED, 199 $ip 200 ) 201 ); 202 return ( 0 < (int) $count ); 203 } 204 205 /** 206 * Delete logs older than the monitoring span and the rejection time. 207 * 208 * @since 2.12.5 209 */ 210 private function delete_expired_logs() { 211 global $wpdb; 212 213 $wpdb->query( 214 $wpdb->prepare( 215 "DELETE FROM {$wpdb->prefix}usces_log WHERE `datetime` <= %s AND `log_type` = %s", 216 $this->get_cutoff_datetime( $this->monitoring ), 217 self::LOG_TYPE_LOGIN_FAILED 218 ) 219 ); 220 $wpdb->query( 221 $wpdb->prepare( 222 "DELETE FROM {$wpdb->prefix}usces_log WHERE `datetime` <= %s AND `log_type` = %s", 223 $this->get_cutoff_datetime( $this->rejection_time ), 224 self::LOG_TYPE_IP_BLOCKED 225 ) 226 ); 227 } 228 229 /** 230 * Get the datetime the specified minutes ago. 231 * 232 * @since 2.12.5 233 * 234 * @param int $minutes Minutes. 235 * @return string 236 */ 237 private function get_cutoff_datetime( $minutes ) { 238 return wp_date( 'Y-m-d H:i:s', time() - ( $minutes * MINUTE_IN_SECONDS ) ); 189 239 } 190 240 } -
usc-e-shop/trunk/classes/usceshop.class.php
r3690880 r3743211 2023 2023 } 2024 2024 2025 // A1 (Layer 3 / uscesid removal): uscesid によるセッションID設定を撤廃。 2026 // かつては GET uscesid を uscesdc() で復号し session_id() に渡していたが、これがセッション 2027 // 固定の温床だった(会員乗っ取り・Mantis #0005562)。決済通知のセッション復元は取引キーの 2028 // DBストア(A3)/同一オリジンの uk cookie 再開(A2/A5/A6)へ移行済みのため撤廃する。 2029 // See .docs/welcart2.x/security-remediation_uscesid-layer3-a1c-teardown-design.md . 2025 // uscesid によるセッションID設定は廃止。決済通知のセッション復元は取引キーの DBストア/ 2026 // 同一オリジンの uk cookie で行う. 2030 2027 2031 2028 do_action( 'usces_action_session_start' ); … … 2072 2069 } 2073 2070 2074 // A1/C (Layer 3 / uscesid removal):旧「GET uscesid を復号して addr='acting' を判定」ブロックを撤廃。2075 // uscesid 機構撤廃に伴い addr 判定は成立しない。以降は旧SSL同期デッドコード( A7 で撤去済)で return.2071 // 旧「GET uscesid を復号して addr='acting' を判定」ブロックを撤廃。 2072 // uscesid 機構撤廃に伴い addr 判定は成立しない。以降は旧SSL同期デッドコード(撤去済)で return. 2076 2073 if ( apply_filters( 'usces_filter_cookie', false ) ) { 2077 2074 return; 2078 2075 } 2079 2076 2080 // NOTE (Layer 3 / uscesid removal, A7): the legacy "common domain + separate SSL domain"2077 // NOTE: the legacy "common domain + separate SSL domain" 2081 2078 // cookie-sync block that used to follow here was already unreachable (an unconditional 2082 2079 // return above) and relied on the old SSL/uscesid scheme. Removed during the uscesid 2083 // mechanism teardown. See .docs/welcart2.x/security-remediation_uscesid-session-fixation.md 4.3.A A7.2080 // mechanism teardown. 2084 2081 return; 2085 2082 } 2086 2083 2087 2084 public function set_cookie( $values, $key = 'usces_cookie' ) { 2088 // A1/C (Layer 3 / uscesid removal):旧実装は uscesid 付きリクエストで再生成をスキップしていたが、2085 // 旧実装は uscesid 付きリクエストで再生成をスキップしていたが、 2089 2086 // uscesid 機構を撤廃したため常に再生成する(=uscesid 以前のオーガニック挙動に一致)。 2090 // 決済のセッション継続は取引キーDBストア (A3)/uk cookie(A2/A5/A6)で担保.2087 // 決済のセッション継続は取引キーDBストア/uk cookie で担保. 2091 2088 session_regenerate_id( true ); 2092 2089 $value = usces_serialize( $values ); … … 2166 2163 2167 2164 /** 2168 * @deprecated A1/C (Layer 3 / uscesid removal). uscesid 機構は撤廃済み(A1)。本体はこの関数を2165 * @deprecated uscesid 機構は撤廃済み。本体はこの関数を 2169 2166 * セッション設定にもURL/nonce生成にも使わない。現状 acting_data の acc_str1 マーカー(save_order_acting_data) 2170 2167 * と、未移行の拡張・クライアントの後方互換のためだけに残置している。**全拡張・全クライアント移行後に … … 2207 2204 * Verify a shop-member nonce. 2208 2205 * 2209 * A1/C (Layer 3 / uscesid removal):移行期の後方互換だった「旧 uscesid ベースキーの二重受理」を撤廃。2206 * 移行期の後方互換だった「旧 uscesid ベースキーの二重受理」を撤廃。 2210 2207 * 以降はセッション束縛の新方式キー(member_nonce_key)のみ受理する。未移行の拡張・テーマの 2211 2208 * フォーム(旧キー生成)は新方式へ移行するまで nonce 不一致になる(協調リリースで同時展開)。 … … 2315 2312 'itemOrderAcceptable': "<?php echo esc_js( $itemOrderAcceptable ); ?>", 2316 2313 'uscespage': "<?php echo esc_js( $wcpage ); ?>", 2317 <?php // A1/C (Layer 3 / uscesid removal):JS グローバル uscesL10n.uscesid の供給を撤廃。消費側は uk cookie 依存へ移行. ?>2314 <?php // JS グローバル uscesL10n.uscesid の供給を撤廃。消費側は uk cookie 依存へ移行. ?> 2318 2315 'wc_nonce': "<?php echo wp_create_nonce( $nonce_action ); ?>" 2319 2316 } … … 3519 3516 3520 3517 $nonce = isset( $_REQUEST['wc_nonce'] ) ? $_REQUEST['wc_nonce'] : ''; 3521 if ( ! $this->verify_member_nonce( $nonce, 'post_member' ) && ! $this->is_member_logged_in() ) { 3522 die( 'Security check2' ); 3518 if ( ! $this->verify_member_nonce( $nonce, 'post_member' ) ) { 3519 if ( ! $this->is_member_logged_in() ) { 3520 die( 'Security check2' ); 3521 } 3522 // ログイン中は nonce 無効の会員情報を登録・更新せず、お客様情報画面を出し直す. 3523 $this->page = 'customer'; 3524 add_filter( 'yoast-ga-push-after-pageview', 'usces_trackPageview_customer' ); 3525 add_action( 'the_post', array( $this, 'action_cartFilter' ) ); 3526 add_action( 'template_redirect', array( $this, 'template_redirect' ) ); 3527 return; 3523 3528 } 3524 3529 $check_verify_recaptcha = $this->verifyGoogleRecapcha(); … … 4876 4881 $nonce = isset( $_REQUEST['wc_nonce'] ) ? $_REQUEST['wc_nonce'] : ''; 4877 4882 } 4878 if ( ! $this->verify_member_nonce( $nonce, 'post_member' ) && ! $this->is_member_logged_in() ) { 4883 if ( ! $this->verify_member_nonce( $nonce, 'post_member' ) ) { 4884 if ( $this->is_member_logged_in() ) { 4885 // ログイン中は nonce 無効の資格情報を処理せず、現在のログイン状態を維持する. 4886 return 'member'; 4887 } 4879 4888 $rateLimiter->saveLoginFailed(); 4880 4889 do_action( 'usces_action_member_login_failed', trim( $_POST['loginmail'] ), 'invalid_nonce' ); … … 8796 8805 8797 8806 /** 8798 * @deprecated A1/C (Layer 3 / uscesid removal).uscesid 難読化生成。本体は不使用。未移行の拡張・8807 * @deprecated uscesid 難読化生成。本体は不使用。未移行の拡張・ 8799 8808 * クライアント後方互換のためのみ残置。全消費側移行後に get_uscesid()/uscesdc() ともども削除する。 8800 8809 */ … … 8833 8842 8834 8843 /** 8835 * @deprecated A1/C (Layer 3 / uscesid removal). uscesid 復号。本体は不使用(A1 で唯一の呼び出しを撤去)。8844 * @deprecated uscesid 復号。本体は不使用(唯一の呼び出しは撤去済み)。 8836 8845 * 未移行の拡張・クライアント(直接 uscesdc()→session_id() する nopriv AJAX)後方互換のためのみ残置。 8837 8846 * 全消費側移行後に get_uscesid()/uscescv() ともども削除する。 -
usc-e-shop/trunk/extensions/BruteForceCountermeasures/brute_force_countermeasures.php
r3191780 r3743211 26 26 27 27 /** 28 * Log file path29 *30 * @var string31 */32 private $uploads_folder_path;33 34 /**35 28 * Class Constructor 36 29 */ 37 30 public function __construct() { 38 31 self::initialize_data(); 39 $this->uploads_folder_path = USCES_WP_CONTENT_DIR . '/uploads';40 32 if ( is_admin() ) { 41 33 add_action( 'usces_action_admin_system_extentions', array( $this, 'setting_form' ) ); … … 81 73 } 82 74 83 if ( ! file_exists( $this->uploads_folder_path ) || ! is_writable( $this->uploads_folder_path ) ) { 84 self::$opts['error_message'] = __( "You can't write to the wp-content/uploads/ folder. Please check the permissions.", 'usces' ); 85 self::$opts['status'] = 0; 86 } else { 87 if ( isset( self::$opts['error_message'] ) ) { 88 unset( self::$opts['error_message'] ); 75 self::$opts['status'] = ( isset( $_POST['brute_force_status'] ) ) ? (int) $_POST['brute_force_status'] : 0; 76 if ( 0 === self::$opts['status'] ) { 77 if ( ! class_exists( 'RateLimiter' ) ) { 78 require USCES_PLUGIN_DIR . '/classes/rateLimiter.class.php'; 89 79 } 90 self::$opts['status'] = ( isset( $_POST['brute_force_status'] ) ) ? (int) $_POST['brute_force_status'] : 0; 91 if ( 0 === self::$opts['status'] ) { 92 $usces_log_folder = USCES_WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . 'usces_logs'; 93 $login_failed_log_path = $usces_log_folder . DIRECTORY_SEPARATOR . 'member_login_failed.log'; 94 $ip_blocked_path = $usces_log_folder . DIRECTORY_SEPARATOR . 'ip_addresses_blocked.log'; 95 if ( file_exists( $login_failed_log_path ) ) { 96 rename( $login_failed_log_path, $usces_log_folder . DIRECTORY_SEPARATOR . 'member_login_failed' . date_i18n( '-YmdHis' ) . '.log' ); 97 } 98 if ( file_exists( $ip_blocked_path ) ) { 99 rename( $ip_blocked_path, $usces_log_folder . DIRECTORY_SEPARATOR . 'ip_addresses_blocked' . date_i18n( '-YmdHis' ) . '.log' ); 100 } 101 } 80 RateLimiter::clear_all(); 102 81 } 103 82 -
usc-e-shop/trunk/extensions/VerifyMembersEmail/verify_members_email.php
r3651924 r3743211 325 325 326 326 $encrypt_value = $this->encrypt_value( $user ); 327 // A1/C (Layer 3 / uscesid removal):検証URL から uscesid を撤去。会員確認は暗号化 verify 値で328 // 行われ session 非依存のため、uscesid は不要 (A1 撤去後は無視される).327 // 検証URL から uscesid を撤去。会員確認は暗号化 verify 値で 328 // 行われ session 非依存のため、uscesid は不要. 329 329 $query = array( 330 330 'verify' => $encrypt_value, -
usc-e-shop/trunk/functions/filters.php
r3690880 r3743211 1891 1891 wp_send_json_error( $res ); 1892 1892 } 1893 // Session fixation remediation (Layer 3 / uscesid removal, A2): reopen the shopper's shop 1894 // session via its own same-origin session cookie instead of decoding a crafted `uscesid` 1895 // through uscesdc()/session_id(). This AJAX runs under admin-ajax.php, where 1896 // usces_close_session() (admin_init) has closed the bootstrap session, so session_status() 1897 // is PHP_SESSION_NONE here and we (re)attach to the frontend shop session identified by its 1898 // cookie. Verified on trunk: the confirm-page uscesid decodes to exactly this cookie's 1899 // session id, so reading the cookie reaches the same cart (result unchanged). 1900 // See .docs/welcart2.x/security-remediation_uscesid-session-fixation.md 4.3.A A2. 1893 // On admin-ajax.php the bootstrap session is already closed by usces_close_session() 1894 // (admin_init), so reopen the shopper's shop session from its session cookie. 1901 1895 if ( PHP_SESSION_NONE === session_status() ) { 1902 1896 $usces_options = get_option( 'usces' ); … … 2283 2277 /* 2284 2278 * Non-acting settlements (cash on delivery, bank transfer and the like) 2285 * used to return here without any nonce check at all, which let a 2286 * crafted request reach order registration without passing through the 2287 * checkout screens. The standard checkout button always emits the 2288 * 'wc_purchase_nonce' field for these settlements (see 2289 * includes/purchase_button.php), so requiring it does not reject a 2290 * legitimate order. Gateway (acting) settlements keep their previous 2291 * behaviour and are handled by the '_purchase_nonce' check below. 2279 * require 'wc_purchase_nonce', which the standard checkout button always 2280 * emits for these settlements (see includes/purchase_button.php). 2281 * Acting settlements are handled by the '_purchase_nonce' check below. 2292 2282 */ 2293 2283 $purchase_nonce = isset( $_POST['wc_purchase_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['wc_purchase_nonce'] ) ) : ''; … … 2368 2358 2369 2359 /* 2370 * Gate: non-acting settlements only, and fail closed when the settlement 2371 * cannot be resolved. usces_get_payments_by_name() returns a stub array 2372 * with a null settlement for an unknown payment name. Treating that as 2373 * "not our concern" would let a forged payment name skip this guard 2374 * entirely, and usces_purchase() only rejects an unresolved payment when 2375 * the order total is greater than zero, so a zero-total order would slip 2376 * through. An unresolved settlement is therefore validated here. 2360 * Non-acting settlements only. A settlement that cannot be resolved 2361 * from the payment name is also validated here (fail closed). 2377 2362 */ 2378 2363 $unresolved = WCUtils::is_blank( $settlement ); … … 2665 2650 * Fires on every successful member login path (member_login() / member_just_login() 2666 2651 * and extension logins that trigger usces_action_after_login). The uscesid mechanism 2667 * itself has been removed (A1/C)and set_cookie() now regenerates unconditionally,2652 * itself has been removed and set_cookie() now regenerates unconditionally, 2668 2653 * but not every login path calls set_cookie() (member_just_login() does not), so this 2669 2654 * hook is what guarantees regeneration on all of them. -
usc-e-shop/trunk/functions/hoock_func.php
r3690880 r3743211 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 notifications10 // Restore the shopper's cart/entry for settlement notifications 11 11 // from the transaction-keyed DB store, uscesid-independently. Must run after usces_session_start() 12 12 // (constructor end) and before usces_main()'s `new usces_cart()`, hence the usces_main hook. … … 26 26 if ( 0 == $_POST['X-ERRLEVEL'] ) { 27 27 $datas = usces_get_order_acting_data( $rand ); 28 // A3:uscesid ブリッジは廃止。セッション復元は usces_restore_acting_session_from_store()(usces_main)で DBストアから実施.28 // uscesid ブリッジは廃止。セッション復元は usces_restore_acting_session_from_store()(usces_main)で DBストアから実施. 29 29 if ( empty( $datas['sesid'] ) ) { 30 30 /* sesidが無い場合はファイルログのみ */ … … 41 41 $sid = wp_unslash( $_POST['SID'] ); 42 42 $datas = usces_get_order_acting_data( $sid ); 43 // A3:uscesid ブリッジは廃止。セッション復元は usces_restore_acting_session_from_store()(usces_main)で DBストアから実施.43 // uscesid ブリッジは廃止。セッション復元は usces_restore_acting_session_from_store()(usces_main)で DBストアから実施. 44 44 if ( empty( $datas['sesid'] ) ) { 45 45 $log = array( … … 60 60 $rand = wp_unslash( $_REQUEST['rand'] ); 61 61 $datas = usces_get_order_acting_data( $rand ); 62 // A3:uscesid ブリッジは廃止。セッション復元は usces_restore_acting_session_from_store()(usces_main)で DBストアから実施.62 // uscesid ブリッジは廃止。セッション復元は usces_restore_acting_session_from_store()(usces_main)で DBストアから実施. 63 63 if ( empty( $datas['sesid'] ) ) { 64 64 $log = array( … … 79 79 $orderid = wp_unslash( $_POST['orderId'] ); 80 80 $datas = usces_get_order_acting_data( $orderid ); 81 // A3:uscesid ブリッジは廃止($_GET['uscesid'] を読む処理は撤廃済みのため代入は無意味だった)。81 // uscesid ブリッジは廃止($_GET['uscesid'] を読む処理は撤廃済みのため代入は無意味だった)。 82 82 // ベリトランス Air-Web は選択可能な決済から除外済み(settlement.class.php)のため、DBストアからの 83 83 // セッション復元(usces_restore_acting_session_from_store)の対象外とする. … … 99 99 /** 100 100 * 決済通知(サーバー間・ブラウザ Cookie 無し)で、確定時に保存したカート/エントリを DBストア 101 * (usces_access)から $_SESSION へ復元する。uscesid セッション橋渡しの置き換え (Layer 3 / A3)。101 * (usces_access)から $_SESSION へ復元する。uscesid セッション橋渡しの置き換え。 102 102 * 103 103 * usces_session_start()(コンストラクタ末尾)より後・usces_main() の `new usces_cart()` より前に … … 665 665 666 666 if ( isset( $data['SEQ'] ) ) { 667 DIGITALCHECK_SETTLEMENT::get_instance()->acting_notice_ip_guard( $data, 'digitalcheck_card' ); 667 668 $table_meta_name = $wpdb->prefix . 'usces_order_meta'; 668 669 $query = $wpdb->prepare( "SELECT `order_id` FROM $table_meta_name WHERE `meta_key` = %s AND `meta_value` = %s", 'SID', $sid ); -
usc-e-shop/trunk/includes/default_filters.php
r3690880 r3743211 231 231 add_action( 'usces_action_session_start', 'usces_session_cache_limiter' ); 232 232 233 // Regenerate session ID on member login (session fixation countermeasure / Layer 1).233 // Regenerate session ID on member login (session fixation countermeasure). 234 234 add_action( 'usces_action_after_login', 'usces_regenerate_session_on_login', 1 ); 235 235 -
usc-e-shop/trunk/readme.txt
r3712726 r3743211 5 5 Tested up to: 7.1 6 6 Requires PHP: 7.4 7 Stable tag: 2.12. 47 Stable tag: 2.12.5 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 60 60 == Frequently Asked Questions == 61 61 62 = Where do I report security bugs found in this plugin? = 63 Please report security vulnerabilities found in the Welcart e-Commerce plugin to support@welcart.com. Please do not post them on the public forum. 64 62 65 Please see [Welcart Forum (Japanese)](https://www.welcart.com/community/forums). 63 66 … … 70 73 == Changelog == 71 74 72 1 7 Sep202673 = V2.12. 4=75 13 Oct 2026 76 = V2.12.5 = 74 77 ----------- 75 * Security enhancement (Cross-Site Scripting). Stopped accepting the notification message on the item list screen from the request parameters, and escaped the output. Thanks to Nguyen Ba Khanh - HPT Vietnam Corporation for the report. 76 * Security enhancement (Cross-Site Scripting). Escaped the output on the 3-D Secure return screen of Paygent. Thanks to Nguyen Ba Khanh - HPT Vietnam Corporation for the report. 77 * Security enhancement. The certificate directory of Paygent is now protected with an access blocking file, and the description of the certificate settings was revised. 78 * Security enhancement. Strengthened the validation of the period specified in the search conditions on the order list screen. 79 * Fixed PHP errors. 80 81 11 Sep 2026 82 = V2.12.3 = 83 ----------- 84 * Security enhancement (Cross-Site Scripting). Escaped the output on the settlement log and the settlement error log screens, and added a client IP check to the Telecom Credit payment notification. Thanks to minhgalaxy - GalaxyOne for the report. 85 * Security enhancement (Missing Authorization). Added an origin check to the payment notification handler of SB Payment Service. 86 * Security enhancement (Missing Authorization). Restricted access to the wcsite linkage endpoint and reduced the setting information output on the administration screen. 87 * The purchase nonce is now required for non-gateway settlements such as cash on delivery and bank transfer, and the entry data is re-validated before an order is registered. Themes that build the checkout form without usces_purchase_button() need to output the wc_purchase_nonce field. 78 * Security enhancement (SQL Injection). Stopped restoring the search condition SQL from the cookie on the old order list screen. Thanks to Wordfence PRISM - Wordfence for the report. 79 * Security enhancement. [PayPal] The order details request of the credit card payment now returns only the order created in the current session. 80 * Security enhancement. The member login and the member information update on the cart page are no longer processed when the nonce verification fails while a member is logged in. 81 * Security enhancement. [Payment For] Added a client IP check to the card payment notification. 82 * Security enhancement. [ZEUS] The payment amount sent to the payment gateway is now taken from the order data instead of the request parameters. 83 * Security enhancement. The log of the login attempt limit is now stored in the database instead of a file. 84 * [Paygent] Fixed the bug that the sending process continued even if the initial setting of the communication failed, and the cause of the error was not displayed correctly. 85 * [Paygent] Fixed the bug that the payment status on the order list and the order edit screen sometimes did not change to the cleared status after the sales processing. 86 * Fixed the bug that orders were not displayed on the old order list screen when the filtered result fit on a single page. 88 87 89 88 For older versions, please see the [Changelog Archive (Japanese)](https://www.welcart.com/about/changelog/). -
usc-e-shop/trunk/usc-e-shop.php
r3699516 r3743211 4 4 * Plugin URI: https://www.welcart.com/ 5 5 * Description: Welcart builds the management system with a net shop on WordPress. 6 * Version: 2.12. 46 * Version: 2.12.5 7 7 * Author: Welcart Inc. 8 8 * Author URI: https://www.welcart.com/ … … 17 17 */ 18 18 19 define( 'USCES_VERSION', '2.12. 4.2609171' );19 define( 'USCES_VERSION', '2.12.5.2610131' ); 20 20 define( 'USCES_DB_ACCESS', '1.5' ); 21 21 define( 'USCES_DB_MEMBER', '1.1' );
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)