|
11 | 11 |
|
12 | 12 | namespace CF7_AntiSpam\Core; |
13 | 13 |
|
| 14 | +use CF7_AntiSpam\Admin\CF7_AntiSpam_Admin_Tools; |
14 | 15 | use Exception; |
15 | 16 | use WPCF7_Submission; |
16 | 17 |
|
@@ -515,23 +516,75 @@ public function filter_plugin_version( $data ) { |
515 | 516 |
|
516 | 517 | $cf7a_version = isset( $_POST[ $prefix . 'version' ] ) ? cf7a_decrypt( sanitize_text_field( wp_unslash( $_POST[ $prefix . 'version' ] ) ), $options['cf7a_cipher'] ) : false; |
517 | 518 |
|
| 519 | + // CASE A: Version field is completely missing or empty -> SPAM |
518 | 520 | if ( ! $cf7a_version ) { |
519 | 521 | $data['spam_score'] += $score_fingerprinting; |
520 | 522 | $data['reasons']['data_mismatch'] = sprintf( "Version mismatch (empty) != '%s'", CF7ANTISPAM_VERSION ); |
521 | 523 | cf7a_log( sprintf( "The 'version' field submitted by %s is empty", $data['remote_ip'] ), 1 ); |
522 | | - } else if ( $cf7a_version !== CF7ANTISPAM_VERSION ) { |
523 | | - // check the last update of the plugin |
524 | | - $last_update = $options['last_update']; |
525 | | - if ( $last_update < time() - WEEK_IN_SECONDS ) { |
526 | | - $data['spam_score'] += $score_fingerprinting; |
527 | | - $data['reasons']['data_mismatch'] = "Version mismatch '$cf7a_version' != '" . CF7ANTISPAM_VERSION . "'"; |
528 | | - cf7a_log( "The 'version' field submitted by {$data['remote_ip']} is empty", 1 ); |
529 | | - } |
530 | | - // Failsafe for cache issues: do not mark as spam, but logic dictates we might unset spam flag |
531 | | - // if it was set purely by accident here (though logic above prevents entry). |
532 | | - // Original code: $spam = false; |
533 | | - // Since we are in a filter, we simply do nothing or reset specific flags if required. |
| 524 | + |
| 525 | + return $data; |
| 526 | + } |
| 527 | + |
| 528 | + // CASE B: Version matches current version -> OK |
| 529 | + if ( $cf7a_version === CF7ANTISPAM_VERSION ) { |
| 530 | + return $data; |
| 531 | + } |
| 532 | + |
| 533 | + // CASE C: Version Mismatch logic (Cache vs Spam) |
| 534 | + // Retrieve update data stored during the last plugin update |
| 535 | + $last_update_data = $options['last_update_data'] ?? null; |
| 536 | + |
| 537 | + // Check if we have update data and if the submitted version matches the PREVIOUS version |
| 538 | + $is_old_version_match = ( $last_update_data && isset( $last_update_data['old_version'] ) && $cf7a_version === $last_update_data['old_version'] ); |
| 539 | + |
| 540 | + // Check if the update happened less than a week ago |
| 541 | + $period_of_grace = apply_filters('cf7a_period_of_grace', WEEK_IN_SECONDS); |
| 542 | + $is_within_grace_period = ( $last_update_data && isset( $last_update_data['time'] ) && ( time() - $last_update_data['time'] ) < $period_of_grace ); |
| 543 | + |
| 544 | + if ( $is_old_version_match && $is_within_grace_period ) { |
| 545 | + |
| 546 | + // --- CACHE ISSUE DETECTED (FALLBACK) --- |
| 547 | + // Do NOT mark as spam. This is likely a cached user. |
| 548 | + |
| 549 | + cf7a_log( "Cache mismatch detected for IP {$data['remote_ip']}. Submitted: $cf7a_version. Expected: " . CF7ANTISPAM_VERSION, 1 ); |
| 550 | + |
| 551 | + // Record the error |
| 552 | + if ( ! isset( $options['last_update_data']['errors'] ) ) { |
| 553 | + $options['last_update_data']['errors'] = array(); |
| 554 | + } |
| 555 | + |
| 556 | + // Add error details |
| 557 | + $options['last_update_data']['errors'][] = array( |
| 558 | + 'ip' => $data['remote_ip'], |
| 559 | + 'time' => time(), |
| 560 | + ); |
| 561 | + |
| 562 | + $error_count = count( $options['last_update_data']['errors'] ); |
| 563 | + |
| 564 | + // Check trigger for email notification (Exactly on the 5th error) |
| 565 | + $cf7a_period_of_grace_max_attempts = intval(apply_filters( 'cf7a_period_of_grace_max_attempts', 5)); |
| 566 | + if ( $cf7a_period_of_grace_max_attempts === $error_count || $error_count * 3 === $cf7a_period_of_grace_max_attempts ) { |
| 567 | + $this->send_cache_warning_email( $options['last_update_data'] ); |
| 568 | + cf7a_log( "Cache warning email sent to admin.", 1 ); |
| 569 | + } |
| 570 | + |
| 571 | + // SAVE OPTIONS: We must save the error count to the database |
| 572 | + // Update the local $options variable first so subsequent filters use it if needed (though unlikely) |
| 573 | + $data['options'] = $options; |
| 574 | + |
| 575 | + // Persist to DB |
| 576 | + update_option( 'cf7a_options', $options ); |
| 577 | + |
| 578 | + } else { |
| 579 | + |
| 580 | + // --- REAL SPAM / INVALID VERSION --- |
| 581 | + // Either the grace period expired, or the version is completely random |
| 582 | + |
| 583 | + $data['spam_score'] += $score_fingerprinting; |
| 584 | + $data['reasons']['data_mismatch'] = "Version mismatch '$cf7a_version' != '" . CF7ANTISPAM_VERSION . "'"; |
| 585 | + cf7a_log( "The 'version' field submitted by {$data['remote_ip']} is mismatching (expired grace period or invalid)", 1 ); |
534 | 586 | } |
| 587 | + |
535 | 588 | return $data; |
536 | 589 | } |
537 | 590 |
|
|
0 commit comments