← All changes
|
app/Services/FluentConversational/Classes/Form.php
+28
-2
6.2.6
→
6.2.15
View file →
| @@ -98,8 +98,9 @@ | ||
| 98 | 98 | 'preview_url' => Helper::getFrontendFacingUrl('?' . $paramKey . '=' . $formId), |
| 99 | 99 | 'fonts' => Fonts::getFonts(), |
| 100 | 100 | 'has_pro' => defined('FLUENTFORMPRO'), |
| 101 | 101 | 'has_pro_share_page' => defined('FLUENTFORMPRO') && class_exists('\FluentFormPro\classes\SharePage\SharePage'), |
| 102 | + 'upgrade_url' => fluentform_upgrade_url(), | |
| 102 | 103 | ]); |
| 103 | 104 | |
| 104 | 105 | wp_enqueue_style( |
| 105 | 106 | 'fluent_forms_conversion_style', |
| @@ -568,9 +569,12 @@ | ||
| 568 | 569 | $instanceId = $form->instance_index; |
| 569 | 570 | $varName = 'fluent_forms_global_var_' . $instanceId; |
| 570 | 571 | |
| 571 | 572 | $localizedVars = [ |
| 572 | - 'fluent_forms_admin_nonce' => wp_create_nonce('fluent_forms_admin_nonce'), | |
| 573 | + // SECURITY (H-01): do not emit the admin AJAX nonce on the public conversational form | |
| 574 | + // page — the public form JS never uses it, and on a page an admin happens to view it | |
| 575 | + // would embed that admin's own valid nonce. Emit it only for a viewer who could use it. | |
| 576 | + 'fluent_forms_admin_nonce' => current_user_can('fluentform_dashboard_access') ? wp_create_nonce('fluent_forms_admin_nonce') : '', | |
| 573 | 577 | 'ajaxurl' => admin_url('admin-ajax.php'), |
| 574 | 578 | 'nonce' => wp_create_nonce(), |
| 575 | 579 | 'form' => $this->getLocalizedForm($form), |
| 576 | 580 | 'assetBaseUrl' => FLUENT_CONVERSATIONAL_FORM_DIR_URL . 'public', |
| @@ -681,8 +685,27 @@ | ||
| 681 | 685 | '_fluentform_' . $formId . '_fluentformnonce' => wp_create_nonce('fluentform-submit-form'), |
| 682 | 686 | '_wp_http_referer' => esc_attr(wp_unslash(wpFluentForm('request')->server('REQUEST_URI'))), |
| 683 | 687 | ]; |
| 684 | 688 | |
| 689 | + // SECURITY (FINDING-25): carry the anti-spam honeypot field (empty) and a freshly minted | |
| 690 | + // token in the conversational submission. The conversational JS forwards every extra_input | |
| 691 | + // into the submission payload, so these reach the server-side checks — which no longer skip | |
| 692 | + // conversational forms — WITHOUT any client/JS change. This closes the bypass where adding | |
| 693 | + // isFFConversational=1 disabled honeypot + token protection entirely. | |
| 694 | + // | |
| 695 | + // The token itself is disabled for conversational forms server-side (see the | |
| 696 | + // fluentform/token_based_spam_protection_status filter in actions.php): its ~1h TTL cannot be | |
| 697 | + // refreshed by the conversational JS, so behind a full-page cache the baked-in token would | |
| 698 | + // expire and reject every submission. getConversationalTokenInput() therefore returns [] for | |
| 699 | + // conversational forms; the honeypot (static empty field) still applies. | |
| 700 | + $honeyPot = new \FluentForm\App\Modules\Form\HoneyPot(wpFluentForm()); | |
| 701 | + $inputs = array_merge($inputs, $honeyPot->getConversationalHoneypotInput($formId)); | |
| 702 | + | |
| 703 | + $inputs = array_merge( | |
| 704 | + $inputs, | |
| 705 | + \FluentForm\App\Modules\Form\TokenBasedSpamProtection::getConversationalTokenInput($formId) | |
| 706 | + ); | |
| 707 | + | |
| 685 | 708 | return apply_filters('fluentform/conversational_extra_inputs', $inputs, $formId); |
| 686 | 709 | } |
| 687 | 710 | |
| 688 | 711 | public function getRandomPhoto() |
| @@ -773,9 +796,12 @@ | ||
| 773 | 796 | |
| 774 | 797 | $designSettings = $this->getDesignSettings($formId); |
| 775 | 798 | |
| 776 | 799 | $localizedVars = [ |
| 777 | - 'fluent_forms_admin_nonce' => wp_create_nonce('fluent_forms_admin_nonce'), | |
| 800 | + // SECURITY (H-01): do not emit the admin AJAX nonce on the public conversational form | |
| 801 | + // page — the public form JS never uses it, and on a page an admin happens to view it | |
| 802 | + // would embed that admin's own valid nonce. Emit it only for a viewer who could use it. | |
| 803 | + 'fluent_forms_admin_nonce' => current_user_can('fluentform_dashboard_access') ? wp_create_nonce('fluent_forms_admin_nonce') : '', | |
| 778 | 804 | 'ajaxurl' => admin_url('admin-ajax.php'), |
| 779 | 805 | 'nonce' => wp_create_nonce(), |
| 780 | 806 | 'form' => $this->getLocalizedForm($form), |
| 781 | 807 | 'form_id' => $form->id, |