| @@ -124,9 +124,8 @@ | ||
| 124 | 124 | add_action( 'wp_ajax_wc_' . $this->get_id() . '_log_js_data', array( $this, 'log_js_data' ) ); |
| 125 | 125 | add_action( 'wp_ajax_nopriv_wc_' . $this->get_id() . '_log_js_data', array( $this, 'log_js_data' ) ); |
| 126 | 126 | |
| 127 | 127 | add_action( 'wp_ajax_wc_' . $this->get_id() . '_get_token_by_id', array( $this, 'get_token_by_id' ) ); |
| 128 | - add_action( 'wp_ajax_nopriv_wc_' . $this->get_id() . '_get_token_by_id', array( $this, 'get_token_by_id' ) ); | |
| 129 | 128 | |
| 130 | 129 | // store the Square item variation ID to order items |
| 131 | 130 | add_action( 'woocommerce_new_order_item', array( $this, 'store_new_order_item_square_meta' ), 10, 3 ); |
| 132 | 131 | |
| @@ -160,22 +159,54 @@ | ||
| 160 | 159 | */ |
| 161 | 160 | public function get_token_by_id() { |
| 162 | 161 | $nonce = isset( $_GET['nonce'] ) ? sanitize_text_field( wp_unslash( $_GET['nonce'] ) ) : false; |
| 163 | 162 | |
| 164 | - if ( ! wp_verify_nonce( $nonce, 'payment_token_nonce' ) ) { | |
| 165 | - wp_send_json_error( esc_html__( 'Nonce verification failed.', 'woocommerce-square' ) ); | |
| 163 | + if ( ! wp_verify_nonce( $nonce, 'payment_token_nonce' ) || ! is_user_logged_in() ) { | |
| 164 | + wp_send_json_error( esc_html__( 'Verification failed.', 'woocommerce-square' ), \WP_Http::UNAUTHORIZED ); | |
| 166 | 165 | } |
| 167 | 166 | |
| 168 | 167 | $token_id = isset( $_GET['token_id'] ) ? absint( wp_unslash( $_GET['token_id'] ) ) : false; |
| 169 | 168 | |
| 170 | 169 | if ( ! $token_id ) { |
| 171 | - wp_send_json_error( esc_html__( 'Token ID missing.', 'woocommerce-square' ) ); | |
| 170 | + wp_send_json_error( esc_html__( 'Token ID missing.', 'woocommerce-square' ), \WP_Http::BAD_REQUEST ); | |
| 172 | 171 | } |
| 173 | 172 | |
| 174 | 173 | $token_obj = \WC_Payment_Tokens::get( $token_id ); |
| 175 | 174 | |
| 175 | + /* | |
| 176 | + * Verify token belongs to this gateway. | |
| 177 | + * | |
| 178 | + * This ajax endpoint is for retrieving Square payment tokens only. | |
| 179 | + */ | |
| 180 | + if ( is_object( $token_obj ) && $this->get_id() !== $token_obj->get_gateway_id() ) { | |
| 181 | + wp_send_json_error( esc_html__( 'Verification failed.', 'woocommerce-square' ), \WP_Http::FORBIDDEN ); | |
| 182 | + } | |
| 183 | + | |
| 184 | + /* | |
| 185 | + * Ensure user has permission to access token. | |
| 186 | + * | |
| 187 | + * Store administrators can request any token but other users can only | |
| 188 | + * access tokens belonging to their own account. | |
| 189 | + */ | |
| 190 | + if ( | |
| 191 | + ! current_user_can( 'manage_woocommerce' ) | |
| 192 | + && ( | |
| 193 | + is_null( $token_obj ) | |
| 194 | + || get_current_user_id() !== $token_obj->get_user_id() | |
| 195 | + ) | |
| 196 | + ) { | |
| 197 | + wp_send_json_error( esc_html__( 'Verification failed.', 'woocommerce-square' ), \WP_Http::FORBIDDEN ); | |
| 198 | + } | |
| 199 | + | |
| 200 | + /* | |
| 201 | + * Show invalid Token ID to store admins only. | |
| 202 | + * | |
| 203 | + * The condition above will present a generic "validation failed" message to other | |
| 204 | + * users, this will only provide the details of why validation failed to store | |
| 205 | + * admins to avoid information disclosure. | |
| 206 | + */ | |
| 176 | 207 | if ( is_null( $token_obj ) ) { |
| 177 | - wp_send_json_error( esc_html__( 'No payment token exists for this ID.', 'woocommerce-square' ) ); | |
| 208 | + wp_send_json_error( esc_html__( 'No payment token exists for this ID.', 'woocommerce-square' ), \WP_Http::NOT_FOUND ); | |
| 178 | 209 | } |
| 179 | 210 | |
| 180 | 211 | wp_send_json_success( $token_obj->get_token() ); |
| 181 | 212 | } |