PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.15
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.15
6.2.15 6.2.14 6.2.13 6.2.12 6.2.10 6.2.11 6.2.9 6.2.8 6.2.7 6.2.6 6.2.5 6.2.4 6.2.3 6.2.2 3.6.22 3.6.31 3.6.40 3.6.41 3.6.42 3.6.50 3.6.51 3.6.60 3.6.61 3.6.62 3.6.64 All 197 releases
← 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,