PluginProbe
GiveWP – Donation Plugin and Fundraising Platform / 4.18.0
GiveWP – Donation Plugin and Fundraising Platform v4.18.0
4.18.0 4.17.0 4.16.9 4.16.8.1 4.16.8 4.16.7.2 4.16.7.1 4.16.7 4.16.6.1 4.16.6 4.16.5.1 4.16.5 4.16.4 4.16.3 4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 All 257 releases
← All changes | includes/class-give-email-access.php +50 -12 2.3.1 → 4.18.0 View file →
@@ -105,9 +105,9 @@
105 105 */
106 106 public function __construct() {
107 107
108 108 // Get it started.
109 - add_action( 'wp', array( $this, 'setup' ) );
109 + add_action( 'wp', [ $this, 'setup' ] );
110 110 }
111 111
112 112 /**
113 113 * Setup hooks
@@ -113,12 +113,15 @@
113 113 * Setup hooks
114 114 *
115 115 * @since 2.4.0
116 116 */
117 - public function setup(){
118 - if( give_is_success_page() || give_is_history_page() ){
117 + public function setup() {
118 +
119 + $is_email_access_on_page = apply_filters( 'give_is_email_access_on_page', give_is_success_page() || give_is_history_page() );
120 +
121 + if ( $is_email_access_on_page ) {
119 122 // Get it started.
120 - add_action( 'wp', array( $this, 'init' ), 14 );
123 + add_action( 'wp', [ $this, 'init' ], 14 );
121 124 }
122 125 }
123 126
124 127 /**
@@ -153,9 +156,9 @@
153 156 $this->check_for_token();
154 157
155 158 if ( $this->token_exists ) {
156 159 add_filter( 'give_user_pending_verification', '__return_false' );
157 - add_filter( 'give_get_users_donations_args', array( $this, 'users_donations_args' ) );
160 + add_filter( 'give_get_users_donations_args', [ $this, 'users_donations_args' ] );
158 161 }
159 162
160 163 }
161 164
@@ -187,9 +190,8 @@
187 190 give_update_meta( $donor_id, '_give_email_throttle_count', 0 );
188 191 Give_Cache::set( $cache_key, true, $this->verify_throttle );
189 192 return false;
190 193 }
191 -
192 194 }
193 195
194 196 return true;
195 197 }
@@ -209,16 +211,17 @@
209 211 return apply_filters( 'give_email-access_email_notification', $donor_id, $email );
210 212 }
211 213
212 214 /**
213 - * Has the user authenticated?
215 + * This function is used to fetch the token value from query string or cookies based on availability.
214 216 *
215 - * @since 1.0
217 + * @since 4.16.7 Return an empty string for non-string token values.
218 + * @since 2.4.1
216 219 * @access public
217 220 *
218 - * @return bool
221 + * @return string
219 222 */
220 - public function check_for_token() {
223 + public function get_token() {
221 224
222 225 $token = isset( $_GET['give_nl'] ) ? give_clean( $_GET['give_nl'] ) : '';
223 226
224 227 // Check for cookie.
@@ -225,8 +228,23 @@
225 228 if ( empty( $token ) ) {
226 229 $token = isset( $_COOKIE['give_nl'] ) ? give_clean( $_COOKIE['give_nl'] ) : '';
227 230 }
228 231
232 + return is_string( $token ) ? $token : '';
233 + }
234 +
235 + /**
236 + * Has the user authenticated?
237 + *
238 + * @since 1.0
239 + * @access public
240 + *
241 + * @return bool
242 + */
243 + public function check_for_token() {
244 +
245 + $token = $this->get_token();
246 +
229 247 // Must have a token.
230 248 if ( ! empty( $token ) ) {
231 249
232 250 if ( ! $this->is_valid_token( $token ) ) {
@@ -235,10 +253,12 @@
235 253 }
236 254 }
237 255
238 256 // Set Receipt Access Session.
257 + Give()->session->maybe_start_session();
239 258 Give()->session->set( 'receipt_access', true );
240 259 $this->token_exists = true;
260 +
241 261 // Set cookie.
242 262 $lifetime = current_time( 'timestamp' ) + Give()->session->set_expiration_time();
243 263 @setcookie( 'give_nl', $token, $lifetime, COOKIEPATH, COOKIE_DOMAIN, false );
244 264
@@ -243,13 +263,16 @@
243 263 @setcookie( 'give_nl', $token, $lifetime, COOKIEPATH, COOKIE_DOMAIN, false );
244 264
245 265 return true;
246 266 }
267 +
268 + return false;
247 269 }
248 270
249 271 /**
250 272 * Is this a valid token?
251 273 *
274 + * @since 4.16.7 Only accept non-empty string tokens.
252 275 * @since 1.0
253 276 * @access public
254 277 *
255 278 * @param $token string The token.
@@ -259,8 +282,13 @@
259 282 public function is_valid_token( $token ) {
260 283
261 284 global $wpdb;
262 285
286 + // A crafted give_nl[]= parameter arrives as an array; reject non-string and empty tokens.
287 + if ( ! is_string( $token ) || '' === $token ) {
288 + return false;
289 + }
290 +
263 291 // Make sure token isn't expired.
264 292 $expires = date( 'Y-m-d H:i:s', time() - $this->token_expiration );
265 293
266 294 $email = $wpdb->get_var(
@@ -322,8 +350,10 @@
322 350
323 351 /**
324 352 * Is this a valid verify key?
325 353 *
354 + * @since 4.18.0 Verify keys expire with the same window as access tokens.
355 + * @since 4.16.7 Only accept non-empty string tokens.
326 356 * @since 1.0
327 357 * @access public
328 358 *
329 359 * @param $token string The token.
@@ -333,11 +363,20 @@
333 363 public function is_valid_verify_key( $token ) {
334 364 /* @var WPDB $wpdb */
335 365 global $wpdb;
336 366
367 + // A crafted give_nl[]= parameter arrives as an array; reject non-string and empty tokens.
368 + if ( ! is_string( $token ) || '' === $token ) {
369 + return false;
370 + }
371 +
372 + // A verify key expires with the same window as an access token, so a
373 + // key generated before that window can no longer be redeemed.
374 + $expires = date( 'Y-m-d H:i:s', time() - $this->token_expiration );
375 +
337 376 // See if the verify_key exists.
338 377 $row = $wpdb->get_row(
339 - $wpdb->prepare( "SELECT id, email FROM {$wpdb->donors} WHERE verify_key = %s LIMIT 1", $token )
378 + $wpdb->prepare( "SELECT id, email FROM {$wpdb->donors} WHERE verify_key = %s AND verify_throttle >= %s LIMIT 1", $token, $expires )
340 379 );
341 380
342 381 $now = date( 'Y-m-d H:i:s' );
343 382
@@ -369,9 +408,8 @@
369 408 * @return mixed
370 409 */
371 410 public function users_donations_args( $args ) {
372 411 $args['user'] = $this->token_email;
373 -
374 412 return $args;
375 413 }
376 414
377 415 /**