Plugin Directory

Changeset 3780268


Ignore:
Timestamp:
11/02/2026 04:22:47 PM (9 hours ago)
Author:
themekraft
Message:

Update to version 2.10.6 from GitHub

Location:
buddyforms
Files:
16 edited
1 copied

Legend:

Unmodified
Added
Removed
  • buddyforms/tags/2.10.6/BuddyForms.php

    r3733032 r3780268  
    88 * Plugin URI:  https://themekraft.com/buddyforms/
    99 * Description: Contact Forms, Post Forms for User Generated Content and Registration Forms easily build in minutes. Extendable with Addons!
    10  * Version: 2.10.5
     10 * Version: 2.10.6
    1111 * Requires at least: 5.9
    1212 * Requires PHP: 7.4
    … …  
    5454         * @var string
    5555         */
    56         public $version = '2.10.5';
     56        public $version = '2.10.6';
    5757
    5858        /**
  • buddyforms/tags/2.10.6/includes/admin/form-builder/meta-boxes/metabox-select-form.php

    r3726654 r3780268  
    9999        }
    100100
    101         $nonce = $_POST['buddyforms_inner_custom_box_nonce'];
     101        $nonce = sanitize_text_field( wp_unslash( $_POST['buddyforms_inner_custom_box_nonce'] ) );
    102102
    103103        // Verify that the nonce is valid.
    … …  
    111111        }
    112112
    113         // Check the user's permissions.
    114         if ( 'page' == $_POST['post_type'] ) {
     113        // Check the user's permissions. edit_post maps to edit_page for pages.
     114        if ( ! current_user_can( 'edit_post', $post_id ) ) {
     115                return $post_id;
     116        }
    115117
    116                 if ( ! current_user_can( 'edit_page', $post_id ) ) {
    117                         return $post_id;
    118                 }
    119         } else {
    120 
    121                 if ( ! current_user_can( 'edit_post', $post_id ) ) {
    122                         return $post_id;
    123                 }
     118        if ( ! isset( $_POST['_bf_form_slug'] ) ) {
     119                return $post_id;
    124120        }
    125121
  • buddyforms/tags/2.10.6/includes/admin/pricing-page-config.php

    r3726654 r3780268  
    3737                                'highlight' => true,
    3838                        ),
    39                         array( 'label' => __( 'BuddyForms', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/frontend-post-form-buddyforms/' ),
    40                         array( 'label' => __( 'BuddyForms ACF', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddyforms-advanced-custom-fields/' ),
    41                         array( 'label' => __( 'BuddyForms Anonymous Author', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddyforms-anonymous-author/' ),
    42                         array( 'label' => __( 'BuddyForms Attach Post with Group', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddypress-group-post/' ),
    43                         array( 'label' => __( 'BuddyForms Custom Login', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/wordpress-custom-login-page/' ),
    44                         array( 'label' => __( 'BuddyForms Geo My WP', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddyforms-geo-my-wp/' ),
    45                         array( 'label' => __( 'BuddyForms Hook Fields', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/display-submissions-data/' ),
    46                         array( 'label' => __( 'BuddyForms Hierarchical Posts', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddyforms-hierarchical-posts/' ),
    47                         array( 'label' => __( 'BuddyForms MailPoet', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddyforms-mailpoet/' ),
    48                         array( 'label' => __( 'BuddyForms Members', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddyforms-buddypress-members/' ),
    49                         array( 'label' => __( 'BuddyForms Moderation', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddyforms-content-moderation/' ),
    50                         array( 'label' => __( 'BuddyForms Pay for Submission', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddyforms-pay-for-submissions/' ),
    51                         array( 'label' => __( 'BuddyForms Pods', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/wordpress-pods-forms/' ),
    52                         array( 'label' => __( 'BuddyForms Post in Groups', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddyforms-buddypress-post-in-groups/' ),
    53                         array( 'label' => __( 'BuddyForms Profile Image', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddypress-profile-image/' ),
    54                         array( 'label' => __( 'BuddyForms Remote', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddyforms-remote-embed-forms/' ),
    55                         array( 'label' => __( 'BuddyForms Ultimate Member', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddyforms-ultimate-member/' ),
    56                         array( 'label' => __( 'BuddyForms WooCommerce Bookings', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddyforms-woocommerce-bookings/' ),
    57                         array( 'label' => __( 'BuddyForms WooCommerce Form Elements', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/woocommerce-form-elements/' ),
    58                         array( 'label' => __( 'BuddyForms WooCommerce Simple Auctions', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddyforms-woocommerce-simple-auction/' ),
     39                        array( 'label' => __( 'BuddyForms', 'buddyforms' ), 'url' => 'https://themekraft.com/plugins/buddyforms/' ),
     40                        array( 'label' => __( 'BuddyForms ACF', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddyforms-advanced-custom-fields/' ),
     41                        array( 'label' => __( 'BuddyForms Anonymous Author', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddyforms-anonymous-author/' ),
     42                        array( 'label' => __( 'BuddyForms Attach Post with Group', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddypress-group-post/' ),
     43                        array( 'label' => __( 'BuddyForms Custom Login', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/wordpress-custom-login-page/' ),
     44                        array( 'label' => __( 'BuddyForms Geo My WP', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddyforms-geo-my-wp/' ),
     45                        array( 'label' => __( 'BuddyForms Hook Fields', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/display-submissions-data/' ),
     46                        array( 'label' => __( 'BuddyForms Hierarchical Posts', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddyforms-hierarchical-posts/' ),
     47                        array( 'label' => __( 'BuddyForms MailPoet', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddyforms-mailpoet/' ),
     48                        array( 'label' => __( 'BuddyForms Members', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddyforms-buddypress-members/' ),
     49                        array( 'label' => __( 'BuddyForms Moderation', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddyforms-content-moderation/' ),
     50                        array( 'label' => __( 'BuddyForms Pay for Submission', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddyforms-pay-for-submissions/' ),
     51                        array( 'label' => __( 'BuddyForms Pods', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/wordpress-pods-forms/' ),
     52                        array( 'label' => __( 'BuddyForms Post in Groups', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddyforms-buddypress-post-in-groups/' ),
     53                        array( 'label' => __( 'BuddyForms Profile Image', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddypress-profile-image/' ),
     54                        array( 'label' => __( 'BuddyForms Remote', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddyforms-remote-embed-forms/' ),
     55                        array( 'label' => __( 'BuddyForms Ultimate Member', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddyforms-ultimate-member/' ),
     56                        array( 'label' => __( 'BuddyForms WooCommerce Bookings', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddyforms-woocommerce-bookings/' ),
     57                        array( 'label' => __( 'BuddyForms WooCommerce Form Elements', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/woocommerce-form-elements/' ),
     58                        array( 'label' => __( 'BuddyForms WooCommerce Simple Auctions', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddyforms-woocommerce-simple-auction/' ),
    5959                        __( 'One year of support', 'buddyforms' ),
    6060                        __( 'One year of updates', 'buddyforms' ),
  • buddyforms/tags/2.10.6/includes/admin/register-post-types.php

    r3731136 r3780268  
    162162        }
    163163
    164         if ( ! empty( $data['post_type'] ) && $data['post_type'] === 'buddyforms' && ! empty( $_POST['buddyforms_options'] ) && ! empty( $_POST['buddyforms_options']['slug'] ) ) {
     164        $form_id = ! empty( $postarr['ID'] ) ? (int) $postarr['ID'] : 0;
     165        if ( ! empty( $data['post_type'] ) && $data['post_type'] === 'buddyforms' && ! empty( $_POST['buddyforms_options'] ) && ! empty( $_POST['buddyforms_options']['slug'] ) && buddyforms_is_form_builder_save( $form_id ) ) {
    165166                $new_slug = sanitize_title( wp_unslash( $_POST['buddyforms_options']['slug'] ) );
    166167                if ( ! empty( $data['post_name'] ) && $data['post_name'] !== $new_slug ) {
    … …  
    178179
    179180/**
     181 * Print the form builder nonce inside the form edit screen's post form.
     182 *
     183 * It is not part of the Form Builder meta box because loading a template replaces that markup.
     184 *
     185 * @param WP_Post $post
     186 *
     187 * @since 2.10.6
     188 */
     189function buddyforms_form_builder_nonce_field( $post ) {
     190        if ( empty( $post ) || $post->post_type !== 'buddyforms' ) {
     191                return;
     192        }
     193
     194        wp_nonce_field( 'buddyforms_form_builder_save_' . $post->ID, 'buddyforms_form_builder_nonce' );
     195}
     196
     197add_action( 'edit_form_top', 'buddyforms_form_builder_nonce_field' );
     198
     199/**
     200 * Check that the current request is a form builder save of this form: the builder's nonce for this
     201 * form and permission to edit it. Front-end submissions never pass this.
     202 *
     203 * @param int $post_id The form post ID.
     204 *
     205 * @return bool
     206 * @since 2.10.6
     207 */
     208function buddyforms_is_form_builder_save( $post_id ) {
     209        if ( empty( $post_id ) || empty( $_POST['buddyforms_form_builder_nonce'] ) || ! is_string( $_POST['buddyforms_form_builder_nonce'] ) ) {
     210                return false;
     211        }
     212
     213        $nonce = sanitize_text_field( wp_unslash( $_POST['buddyforms_form_builder_nonce'] ) );
     214        if ( ! wp_verify_nonce( $nonce, 'buddyforms_form_builder_save_' . $post_id ) ) {
     215                return false;
     216        }
     217
     218        return current_user_can( 'edit_post', $post_id );
     219}
     220
     221/**
     222 * Form settings that decide who can submit a form and what it does with the submission.
     223 * A request from the front end can never change them, whatever else it may save.
     224 *
     225 * @return array
     226 * @since 2.10.6
     227 */
     228function buddyforms_form_protected_options() {
     229        return array( 'form_type', 'public_submit', 'public_submit_create_account', 'registration' );
     230}
     231
     232/**
    180233 * Adds a box to the main column on the Post and Page edit screens.
    181234 *
    … …  
    197250        }
    198251
     252        if ( ! buddyforms_is_form_builder_save( $post_id ) ) {
     253                return;
     254        }
     255
    199256        $buddyform = buddyforms_sanitize( '', wp_unslash( $_POST['buddyforms_options'] ) );
     257        if ( ! is_array( $buddyform ) ) {
     258                return;
     259        }
     260
     261        // Outside wp-admin, keep the stored values of the settings that control public access.
     262        if ( ! is_admin() || ! is_user_logged_in() ) {
     263                $stored_options = get_post_meta( $post_id, '_buddyforms_options', true );
     264                foreach ( buddyforms_form_protected_options() as $option_key ) {
     265                        if ( is_array( $stored_options ) && array_key_exists( $option_key, $stored_options ) ) {
     266                                $buddyform[ $option_key ] = $stored_options[ $option_key ];
     267                        } else {
     268                                unset( $buddyform[ $option_key ] );
     269                        }
     270                }
     271        }
    200272
    201273        // Add post title as form name and post name as form slug.
    … …  
    216288        update_post_meta( $post_id, '_buddyforms_options', $buddyform );
    217289
    218         $form_type = $buddyform['form_type'];
     290        $form_type = isset( $buddyform['form_type'] ) ? $buddyform['form_type'] : '';
    219291
    220292        // Save the Roles and capabilities.
    … …  
    254326        buddyforms_attached_page_rewrite_rules( true );
    255327
    256         buddyforms_track( 'builder-save', array( 'form-type' => $buddyform['form_type'] ) );
     328        buddyforms_track( 'builder-save', array( 'form-type' => $form_type ) );
    257329
    258330        do_action( 'buddyforms_after_update_form_options', $buddyform['slug'], $buddyform, $post );
  • buddyforms/tags/2.10.6/includes/form/form-control.php

    r3726722 r3780268  
    121121
    122122                return $args;
     123        }
     124
     125        // The post type always comes from the saved form. The request's bf_post_type (and post_type) is
     126        // ignored, so a submission can never create or edit posts of another type, forms included.
     127        $post_type = buddyforms_get_form_post_type( $form_slug );
     128        if ( buddyforms_is_submission_post_type_blocked( $post_type ) ) {
     129                return array(
     130                        'hasError'      => true,
     131                        'form_slug'     => $form_slug,
     132                        'error_message' => __( 'Form submit error. Please contact the site administrator.', 'buddyforms' ),
     133                );
    123134        }
    124135
    … …  
    255266        do_action( 'buddyforms_process_submission_start', $args );
    256267
    257         if ( isset( $_POST['bf_post_type'] ) ) {
    258                 $post_type = sanitize_text_field( wp_unslash( $_POST['bf_post_type'] ) );
    259         }
    260 
    261268        if ( $post_id != 0 && $form_type !== 'registration' ) {
    262269                if ( ! empty( $revision_id ) ) {
    … …  
    267274                }
    268275
    269                 // Check if the post to edit match with the form setting. An existing post must match the form's
    270                 // post type, not the one sent in the request.
    271                 $target_post        = get_post( $post_id );
    272                 $expected_post_type = $post_type;
    273                 if ( ! empty( $target_post ) && $target_post->post_status !== 'auto-draft' && ! empty( $buddyforms[ $form_slug ]['post_type'] ) ) {
    274                         $expected_post_type = $buddyforms[ $form_slug ]['post_type'];
    275                 }
    276                 if ( empty( $target_post ) || $target_post->post_type !== $expected_post_type ) {
     276                // The post to edit, auto-drafts included, must be of the form's post type.
     277                $target_post = get_post( $post_id );
     278                if ( empty( $target_post ) || $target_post->post_type !== $post_type ) {
    277279                        $args = array(
    278280                                'hasError'      => true,
    … …  
    453455        $args = buddyforms_update_post( $args );
    454456
     457        // A new post (post_id 0) only gets its ID, or the WP_Error, from the update.
     458        if ( isset( $args['post_id'] ) ) {
     459                $post_id = $args['post_id'];
     460        }
     461
    455462        /*
    456463         * Check if the update or insert was successful
    … …  
    509516        } else {
    510517                $hasError      = true;
    511                 $error_message = $post_id->get_error_message();
     518                $error_message = is_wp_error( $post_id ) ? $post_id->get_error_message() : __( 'Form submit error. Please contact the site administrator.', 'buddyforms' );
    512519                $global_error->add_error( new BuddyForms_Error( 'buddyforms_form_' . $form_slug, $error_message, '', $form_slug ) );
    513520        }
    … …  
    551558
    552559        return $args;
     560}
     561
     562/**
     563 * Get the post type a form saves its entries as, taken from the saved form settings only.
     564 *
     565 * Callers must refuse the types buddyforms_is_submission_post_type_blocked() reports.
     566 *
     567 * @param string $form_slug
     568 *
     569 * @return string
     570 * @since 2.10.6
     571 */
     572function buddyforms_get_form_post_type( $form_slug ) {
     573        global $buddyforms;
     574
     575        $post_type = '';
     576        if ( ! empty( $buddyforms[ $form_slug ]['post_type'] ) && is_string( $buddyforms[ $form_slug ]['post_type'] ) ) {
     577                $post_type = $buddyforms[ $form_slug ]['post_type'];
     578        }
     579
     580        /**
     581         * Filter the post type a form submission is saved as.
     582         *
     583         * @param string $post_type The post type from the form settings.
     584         * @param string $form_slug The form slug.
     585         *
     586         * @since 2.10.6
     587         */
     588        $post_type = apply_filters( 'buddyforms_submission_post_type', $post_type, $form_slug );
     589
     590        return is_string( $post_type ) ? $post_type : '';
     591}
     592
     593/**
     594 * Whether a post type can never be the target of a front-end submission.
     595 *
     596 * These types are internal to WordPress or BuddyForms (the forms themselves, Customizer changesets,
     597 * menu items, privacy requests, ...). Saving a public submission as one of them would let a visitor
     598 * write configuration or content that core acts on.
     599 *
     600 * @param string $post_type
     601 *
     602 * @return bool
     603 * @since 2.10.6
     604 */
     605function buddyforms_is_submission_post_type_blocked( $post_type ) {
     606        $blocked = apply_filters(
     607                'buddyforms_submission_blocked_post_types',
     608                array( 'buddyforms', 'customize_changeset', 'nav_menu_item', 'user_request', 'oembed_cache', 'revision', 'wp_template', 'wp_template_part', 'wp_global_styles', 'wp_navigation', 'wp_block' )
     609        );
     610
     611        return in_array( $post_type, (array) $blocked, true );
    553612}
    554613
  • buddyforms/tags/2.10.6/includes/wp-insert-user.php

    r3726654 r3780268  
    136136}
    137137
     138/**
     139 * Check if a role can be given to a visitor who registers through a form.
     140 *
     141 * Roles with any of the blocked capabilities are refused. A role that does not exist grants nothing.
     142 *
     143 * @param string $role      Role slug from the form settings.
     144 * @param string $form_slug The form slug.
     145 *
     146 * @return bool
     147 * @since 2.10.6
     148 */
     149function buddyforms_is_registration_role_allowed( $role, $form_slug = '' ) {
     150        if ( ! is_string( $role ) ) {
     151                return false;
     152        }
     153
     154        $role_object = get_role( $role );
     155        if ( empty( $role_object ) ) {
     156                return true;
     157        }
     158
     159        /**
     160         * Filter the capabilities a role must not have to be given to a visitor who registers through a form.
     161         *
     162         * @param array  $capabilities Blocked capabilities.
     163         * @param string $role         Role slug from the form settings.
     164         * @param string $form_slug    The form slug.
     165         *
     166         * @since 2.10.6
     167         */
     168        $blocked_capabilities = apply_filters(
     169                'buddyforms_registration_blocked_capabilities',
     170                array( 'manage_options', 'promote_users', 'edit_users', 'create_users', 'install_plugins' ),
     171                $role,
     172                $form_slug
     173        );
     174
     175        foreach ( (array) $blocked_capabilities as $capability ) {
     176                if ( $role_object->has_cap( $capability ) ) {
     177                        return false;
     178                }
     179        }
     180
     181        return true;
     182}
     183
    138184// register a new user
    139185/**
    … …  
    236282
    237283        $user_role = isset( $buddyforms[ $form_slug ]['registration']['new_user_role'] ) ? $buddyforms[ $form_slug ]['registration']['new_user_role'] : 'subscriber';
     284
     285        // A visitor can never register with a role that can manage the site, whatever the form says.
     286        if ( ! $hasError && ! is_user_logged_in() && ! buddyforms_is_registration_role_allowed( $user_role, $form_slug ) ) {
     287                $hasError = true;
     288                $global_error->add_error( new BuddyForms_Error( 'buddyforms_form_' . $form_slug, __( 'Registration is not available with this form. Please contact the site administrator.', 'buddyforms' ), '', $form_slug ) );
     289        }
    238290
    239291        // only create the user in if there are no errors
  • buddyforms/tags/2.10.6/readme.txt

    r3733032 r3780268  
    44Requires at least: 5.9
    55Tested up to: 7.1
    6 Stable tag: 2.10.5
     6Stable tag: 2.10.6
    77Requires PHP: 7.4
    88License: GPLv2
    … …  
    265265
    266266== Changelog ==
     267= 2.10.6 - 19 Oct 2026 =
     268* Security: front-end submissions always save entries as the post type configured in the form, and never as WordPress-internal types or as forms.
     269* Security: anonymous registration cannot assign a role that can manage the site or its users. The list of blocked capabilities can be changed with the `buddyforms_registration_blocked_capabilities` filter.
     270* Security: saving a form in the form builder and saving the entry fields meta box now check a nonce and the user's permission to edit the post.
     271* Changed: the `post_type` attribute of the `[buddyforms_form]` shortcode no longer changes the post type entries are saved as. Use the `buddyforms_submission_post_type` filter instead.
     272* Fixed a fatal error when a submission arrived without an entry ID.
     273* Updated the Go Pro links to the current themekraft.com product pages.
    267274= 2.10.5 - 07 Oct 2026 =
    268275* Fixed a fatal error when activating the premium version while the free version is active. Activating one version now deactivates the other one.
  • buddyforms/tags/2.10.6/vendor/composer/installed.php

    r3733032 r3780268  
    22    'root' => array(
    33        'name' => 'themekraft/buddyforms',
    4         'pretty_version' => '2.10.5',
    5         'version' => '2.10.5.0',
    6         'reference' => 'da2f8a1863648fc7eeb253a05ff2dad5e75b4672',
     4        'pretty_version' => '2.10.6',
     5        'version' => '2.10.6.0',
     6        'reference' => '55fb036638e1eb2b203df5a05e800cfee608cc65',
    77        'type' => 'wordpress-plugin',
    88        'install_path' => __DIR__ . '/../../',
    … …  
    2121        ),
    2222        'themekraft/buddyforms' => array(
    23             'pretty_version' => '2.10.5',
    24             'version' => '2.10.5.0',
    25             'reference' => 'da2f8a1863648fc7eeb253a05ff2dad5e75b4672',
     23            'pretty_version' => '2.10.6',
     24            'version' => '2.10.6.0',
     25            'reference' => '55fb036638e1eb2b203df5a05e800cfee608cc65',
    2626            'type' => 'wordpress-plugin',
    2727            'install_path' => __DIR__ . '/../../',
  • buddyforms/trunk/BuddyForms.php

    r3733032 r3780268  
    88 * Plugin URI:  https://themekraft.com/buddyforms/
    99 * Description: Contact Forms, Post Forms for User Generated Content and Registration Forms easily build in minutes. Extendable with Addons!
    10  * Version: 2.10.5
     10 * Version: 2.10.6
    1111 * Requires at least: 5.9
    1212 * Requires PHP: 7.4
    … …  
    5454         * @var string
    5555         */
    56         public $version = '2.10.5';
     56        public $version = '2.10.6';
    5757
    5858        /**
  • buddyforms/trunk/includes/admin/form-builder/meta-boxes/metabox-select-form.php

    r3726654 r3780268  
    9999        }
    100100
    101         $nonce = $_POST['buddyforms_inner_custom_box_nonce'];
     101        $nonce = sanitize_text_field( wp_unslash( $_POST['buddyforms_inner_custom_box_nonce'] ) );
    102102
    103103        // Verify that the nonce is valid.
    … …  
    111111        }
    112112
    113         // Check the user's permissions.
    114         if ( 'page' == $_POST['post_type'] ) {
     113        // Check the user's permissions. edit_post maps to edit_page for pages.
     114        if ( ! current_user_can( 'edit_post', $post_id ) ) {
     115                return $post_id;
     116        }
    115117
    116                 if ( ! current_user_can( 'edit_page', $post_id ) ) {
    117                         return $post_id;
    118                 }
    119         } else {
    120 
    121                 if ( ! current_user_can( 'edit_post', $post_id ) ) {
    122                         return $post_id;
    123                 }
     118        if ( ! isset( $_POST['_bf_form_slug'] ) ) {
     119                return $post_id;
    124120        }
    125121
  • buddyforms/trunk/includes/admin/pricing-page-config.php

    r3726654 r3780268  
    3737                                'highlight' => true,
    3838                        ),
    39                         array( 'label' => __( 'BuddyForms', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/frontend-post-form-buddyforms/' ),
    40                         array( 'label' => __( 'BuddyForms ACF', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddyforms-advanced-custom-fields/' ),
    41                         array( 'label' => __( 'BuddyForms Anonymous Author', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddyforms-anonymous-author/' ),
    42                         array( 'label' => __( 'BuddyForms Attach Post with Group', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddypress-group-post/' ),
    43                         array( 'label' => __( 'BuddyForms Custom Login', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/wordpress-custom-login-page/' ),
    44                         array( 'label' => __( 'BuddyForms Geo My WP', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddyforms-geo-my-wp/' ),
    45                         array( 'label' => __( 'BuddyForms Hook Fields', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/display-submissions-data/' ),
    46                         array( 'label' => __( 'BuddyForms Hierarchical Posts', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddyforms-hierarchical-posts/' ),
    47                         array( 'label' => __( 'BuddyForms MailPoet', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddyforms-mailpoet/' ),
    48                         array( 'label' => __( 'BuddyForms Members', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddyforms-buddypress-members/' ),
    49                         array( 'label' => __( 'BuddyForms Moderation', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddyforms-content-moderation/' ),
    50                         array( 'label' => __( 'BuddyForms Pay for Submission', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddyforms-pay-for-submissions/' ),
    51                         array( 'label' => __( 'BuddyForms Pods', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/wordpress-pods-forms/' ),
    52                         array( 'label' => __( 'BuddyForms Post in Groups', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddyforms-buddypress-post-in-groups/' ),
    53                         array( 'label' => __( 'BuddyForms Profile Image', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddypress-profile-image/' ),
    54                         array( 'label' => __( 'BuddyForms Remote', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddyforms-remote-embed-forms/' ),
    55                         array( 'label' => __( 'BuddyForms Ultimate Member', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddyforms-ultimate-member/' ),
    56                         array( 'label' => __( 'BuddyForms WooCommerce Bookings', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddyforms-woocommerce-bookings/' ),
    57                         array( 'label' => __( 'BuddyForms WooCommerce Form Elements', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/woocommerce-form-elements/' ),
    58                         array( 'label' => __( 'BuddyForms WooCommerce Simple Auctions', 'buddyforms' ), 'url' => 'https://themekraft.com/wordpress-products/buddyforms-woocommerce-simple-auction/' ),
     39                        array( 'label' => __( 'BuddyForms', 'buddyforms' ), 'url' => 'https://themekraft.com/plugins/buddyforms/' ),
     40                        array( 'label' => __( 'BuddyForms ACF', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddyforms-advanced-custom-fields/' ),
     41                        array( 'label' => __( 'BuddyForms Anonymous Author', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddyforms-anonymous-author/' ),
     42                        array( 'label' => __( 'BuddyForms Attach Post with Group', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddypress-group-post/' ),
     43                        array( 'label' => __( 'BuddyForms Custom Login', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/wordpress-custom-login-page/' ),
     44                        array( 'label' => __( 'BuddyForms Geo My WP', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddyforms-geo-my-wp/' ),
     45                        array( 'label' => __( 'BuddyForms Hook Fields', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/display-submissions-data/' ),
     46                        array( 'label' => __( 'BuddyForms Hierarchical Posts', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddyforms-hierarchical-posts/' ),
     47                        array( 'label' => __( 'BuddyForms MailPoet', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddyforms-mailpoet/' ),
     48                        array( 'label' => __( 'BuddyForms Members', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddyforms-buddypress-members/' ),
     49                        array( 'label' => __( 'BuddyForms Moderation', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddyforms-content-moderation/' ),
     50                        array( 'label' => __( 'BuddyForms Pay for Submission', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddyforms-pay-for-submissions/' ),
     51                        array( 'label' => __( 'BuddyForms Pods', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/wordpress-pods-forms/' ),
     52                        array( 'label' => __( 'BuddyForms Post in Groups', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddyforms-buddypress-post-in-groups/' ),
     53                        array( 'label' => __( 'BuddyForms Profile Image', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddypress-profile-image/' ),
     54                        array( 'label' => __( 'BuddyForms Remote', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddyforms-remote-embed-forms/' ),
     55                        array( 'label' => __( 'BuddyForms Ultimate Member', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddyforms-ultimate-member/' ),
     56                        array( 'label' => __( 'BuddyForms WooCommerce Bookings', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddyforms-woocommerce-bookings/' ),
     57                        array( 'label' => __( 'BuddyForms WooCommerce Form Elements', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/woocommerce-form-elements/' ),
     58                        array( 'label' => __( 'BuddyForms WooCommerce Simple Auctions', 'buddyforms' ), 'url' => 'https://themekraft.com/add-on/buddyforms-woocommerce-simple-auction/' ),
    5959                        __( 'One year of support', 'buddyforms' ),
    6060                        __( 'One year of updates', 'buddyforms' ),
  • buddyforms/trunk/includes/admin/register-post-types.php

    r3731136 r3780268  
    162162        }
    163163
    164         if ( ! empty( $data['post_type'] ) && $data['post_type'] === 'buddyforms' && ! empty( $_POST['buddyforms_options'] ) && ! empty( $_POST['buddyforms_options']['slug'] ) ) {
     164        $form_id = ! empty( $postarr['ID'] ) ? (int) $postarr['ID'] : 0;
     165        if ( ! empty( $data['post_type'] ) && $data['post_type'] === 'buddyforms' && ! empty( $_POST['buddyforms_options'] ) && ! empty( $_POST['buddyforms_options']['slug'] ) && buddyforms_is_form_builder_save( $form_id ) ) {
    165166                $new_slug = sanitize_title( wp_unslash( $_POST['buddyforms_options']['slug'] ) );
    166167                if ( ! empty( $data['post_name'] ) && $data['post_name'] !== $new_slug ) {
    … …  
    178179
    179180/**
     181 * Print the form builder nonce inside the form edit screen's post form.
     182 *
     183 * It is not part of the Form Builder meta box because loading a template replaces that markup.
     184 *
     185 * @param WP_Post $post
     186 *
     187 * @since 2.10.6
     188 */
     189function buddyforms_form_builder_nonce_field( $post ) {
     190        if ( empty( $post ) || $post->post_type !== 'buddyforms' ) {
     191                return;
     192        }
     193
     194        wp_nonce_field( 'buddyforms_form_builder_save_' . $post->ID, 'buddyforms_form_builder_nonce' );
     195}
     196
     197add_action( 'edit_form_top', 'buddyforms_form_builder_nonce_field' );
     198
     199/**
     200 * Check that the current request is a form builder save of this form: the builder's nonce for this
     201 * form and permission to edit it. Front-end submissions never pass this.
     202 *
     203 * @param int $post_id The form post ID.
     204 *
     205 * @return bool
     206 * @since 2.10.6
     207 */
     208function buddyforms_is_form_builder_save( $post_id ) {
     209        if ( empty( $post_id ) || empty( $_POST['buddyforms_form_builder_nonce'] ) || ! is_string( $_POST['buddyforms_form_builder_nonce'] ) ) {
     210                return false;
     211        }
     212
     213        $nonce = sanitize_text_field( wp_unslash( $_POST['buddyforms_form_builder_nonce'] ) );
     214        if ( ! wp_verify_nonce( $nonce, 'buddyforms_form_builder_save_' . $post_id ) ) {
     215                return false;
     216        }
     217
     218        return current_user_can( 'edit_post', $post_id );
     219}
     220
     221/**
     222 * Form settings that decide who can submit a form and what it does with the submission.
     223 * A request from the front end can never change them, whatever else it may save.
     224 *
     225 * @return array
     226 * @since 2.10.6
     227 */
     228function buddyforms_form_protected_options() {
     229        return array( 'form_type', 'public_submit', 'public_submit_create_account', 'registration' );
     230}
     231
     232/**
    180233 * Adds a box to the main column on the Post and Page edit screens.
    181234 *
    … …  
    197250        }
    198251
     252        if ( ! buddyforms_is_form_builder_save( $post_id ) ) {
     253                return;
     254        }
     255
    199256        $buddyform = buddyforms_sanitize( '', wp_unslash( $_POST['buddyforms_options'] ) );
     257        if ( ! is_array( $buddyform ) ) {
     258                return;
     259        }
     260
     261        // Outside wp-admin, keep the stored values of the settings that control public access.
     262        if ( ! is_admin() || ! is_user_logged_in() ) {
     263                $stored_options = get_post_meta( $post_id, '_buddyforms_options', true );
     264                foreach ( buddyforms_form_protected_options() as $option_key ) {
     265                        if ( is_array( $stored_options ) && array_key_exists( $option_key, $stored_options ) ) {
     266                                $buddyform[ $option_key ] = $stored_options[ $option_key ];
     267                        } else {
     268                                unset( $buddyform[ $option_key ] );
     269                        }
     270                }
     271        }
    200272
    201273        // Add post title as form name and post name as form slug.
    … …  
    216288        update_post_meta( $post_id, '_buddyforms_options', $buddyform );
    217289
    218         $form_type = $buddyform['form_type'];
     290        $form_type = isset( $buddyform['form_type'] ) ? $buddyform['form_type'] : '';
    219291
    220292        // Save the Roles and capabilities.
    … …  
    254326        buddyforms_attached_page_rewrite_rules( true );
    255327
    256         buddyforms_track( 'builder-save', array( 'form-type' => $buddyform['form_type'] ) );
     328        buddyforms_track( 'builder-save', array( 'form-type' => $form_type ) );
    257329
    258330        do_action( 'buddyforms_after_update_form_options', $buddyform['slug'], $buddyform, $post );
  • buddyforms/trunk/includes/form/form-control.php

    r3726722 r3780268  
    121121
    122122                return $args;
     123        }
     124
     125        // The post type always comes from the saved form. The request's bf_post_type (and post_type) is
     126        // ignored, so a submission can never create or edit posts of another type, forms included.
     127        $post_type = buddyforms_get_form_post_type( $form_slug );
     128        if ( buddyforms_is_submission_post_type_blocked( $post_type ) ) {
     129                return array(
     130                        'hasError'      => true,
     131                        'form_slug'     => $form_slug,
     132                        'error_message' => __( 'Form submit error. Please contact the site administrator.', 'buddyforms' ),
     133                );
    123134        }
    124135
    … …  
    255266        do_action( 'buddyforms_process_submission_start', $args );
    256267
    257         if ( isset( $_POST['bf_post_type'] ) ) {
    258                 $post_type = sanitize_text_field( wp_unslash( $_POST['bf_post_type'] ) );
    259         }
    260 
    261268        if ( $post_id != 0 && $form_type !== 'registration' ) {
    262269                if ( ! empty( $revision_id ) ) {
    … …  
    267274                }
    268275
    269                 // Check if the post to edit match with the form setting. An existing post must match the form's
    270                 // post type, not the one sent in the request.
    271                 $target_post        = get_post( $post_id );
    272                 $expected_post_type = $post_type;
    273                 if ( ! empty( $target_post ) && $target_post->post_status !== 'auto-draft' && ! empty( $buddyforms[ $form_slug ]['post_type'] ) ) {
    274                         $expected_post_type = $buddyforms[ $form_slug ]['post_type'];
    275                 }
    276                 if ( empty( $target_post ) || $target_post->post_type !== $expected_post_type ) {
     276                // The post to edit, auto-drafts included, must be of the form's post type.
     277                $target_post = get_post( $post_id );
     278                if ( empty( $target_post ) || $target_post->post_type !== $post_type ) {
    277279                        $args = array(
    278280                                'hasError'      => true,
    … …  
    453455        $args = buddyforms_update_post( $args );
    454456
     457        // A new post (post_id 0) only gets its ID, or the WP_Error, from the update.
     458        if ( isset( $args['post_id'] ) ) {
     459                $post_id = $args['post_id'];
     460        }
     461
    455462        /*
    456463         * Check if the update or insert was successful
    … …  
    509516        } else {
    510517                $hasError      = true;
    511                 $error_message = $post_id->get_error_message();
     518                $error_message = is_wp_error( $post_id ) ? $post_id->get_error_message() : __( 'Form submit error. Please contact the site administrator.', 'buddyforms' );
    512519                $global_error->add_error( new BuddyForms_Error( 'buddyforms_form_' . $form_slug, $error_message, '', $form_slug ) );
    513520        }
    … …  
    551558
    552559        return $args;
     560}
     561
     562/**
     563 * Get the post type a form saves its entries as, taken from the saved form settings only.
     564 *
     565 * Callers must refuse the types buddyforms_is_submission_post_type_blocked() reports.
     566 *
     567 * @param string $form_slug
     568 *
     569 * @return string
     570 * @since 2.10.6
     571 */
     572function buddyforms_get_form_post_type( $form_slug ) {
     573        global $buddyforms;
     574
     575        $post_type = '';
     576        if ( ! empty( $buddyforms[ $form_slug ]['post_type'] ) && is_string( $buddyforms[ $form_slug ]['post_type'] ) ) {
     577                $post_type = $buddyforms[ $form_slug ]['post_type'];
     578        }
     579
     580        /**
     581         * Filter the post type a form submission is saved as.
     582         *
     583         * @param string $post_type The post type from the form settings.
     584         * @param string $form_slug The form slug.
     585         *
     586         * @since 2.10.6
     587         */
     588        $post_type = apply_filters( 'buddyforms_submission_post_type', $post_type, $form_slug );
     589
     590        return is_string( $post_type ) ? $post_type : '';
     591}
     592
     593/**
     594 * Whether a post type can never be the target of a front-end submission.
     595 *
     596 * These types are internal to WordPress or BuddyForms (the forms themselves, Customizer changesets,
     597 * menu items, privacy requests, ...). Saving a public submission as one of them would let a visitor
     598 * write configuration or content that core acts on.
     599 *
     600 * @param string $post_type
     601 *
     602 * @return bool
     603 * @since 2.10.6
     604 */
     605function buddyforms_is_submission_post_type_blocked( $post_type ) {
     606        $blocked = apply_filters(
     607                'buddyforms_submission_blocked_post_types',
     608                array( 'buddyforms', 'customize_changeset', 'nav_menu_item', 'user_request', 'oembed_cache', 'revision', 'wp_template', 'wp_template_part', 'wp_global_styles', 'wp_navigation', 'wp_block' )
     609        );
     610
     611        return in_array( $post_type, (array) $blocked, true );
    553612}
    554613
  • buddyforms/trunk/includes/wp-insert-user.php

    r3726654 r3780268  
    136136}
    137137
     138/**
     139 * Check if a role can be given to a visitor who registers through a form.
     140 *
     141 * Roles with any of the blocked capabilities are refused. A role that does not exist grants nothing.
     142 *
     143 * @param string $role      Role slug from the form settings.
     144 * @param string $form_slug The form slug.
     145 *
     146 * @return bool
     147 * @since 2.10.6
     148 */
     149function buddyforms_is_registration_role_allowed( $role, $form_slug = '' ) {
     150        if ( ! is_string( $role ) ) {
     151                return false;
     152        }
     153
     154        $role_object = get_role( $role );
     155        if ( empty( $role_object ) ) {
     156                return true;
     157        }
     158
     159        /**
     160         * Filter the capabilities a role must not have to be given to a visitor who registers through a form.
     161         *
     162         * @param array  $capabilities Blocked capabilities.
     163         * @param string $role         Role slug from the form settings.
     164         * @param string $form_slug    The form slug.
     165         *
     166         * @since 2.10.6
     167         */
     168        $blocked_capabilities = apply_filters(
     169                'buddyforms_registration_blocked_capabilities',
     170                array( 'manage_options', 'promote_users', 'edit_users', 'create_users', 'install_plugins' ),
     171                $role,
     172                $form_slug
     173        );
     174
     175        foreach ( (array) $blocked_capabilities as $capability ) {
     176                if ( $role_object->has_cap( $capability ) ) {
     177                        return false;
     178                }
     179        }
     180
     181        return true;
     182}
     183
    138184// register a new user
    139185/**
    … …  
    236282
    237283        $user_role = isset( $buddyforms[ $form_slug ]['registration']['new_user_role'] ) ? $buddyforms[ $form_slug ]['registration']['new_user_role'] : 'subscriber';
     284
     285        // A visitor can never register with a role that can manage the site, whatever the form says.
     286        if ( ! $hasError && ! is_user_logged_in() && ! buddyforms_is_registration_role_allowed( $user_role, $form_slug ) ) {
     287                $hasError = true;
     288                $global_error->add_error( new BuddyForms_Error( 'buddyforms_form_' . $form_slug, __( 'Registration is not available with this form. Please contact the site administrator.', 'buddyforms' ), '', $form_slug ) );
     289        }
    238290
    239291        // only create the user in if there are no errors
  • buddyforms/trunk/readme.txt

    r3733032 r3780268  
    44Requires at least: 5.9
    55Tested up to: 7.1
    6 Stable tag: 2.10.5
     6Stable tag: 2.10.6
    77Requires PHP: 7.4
    88License: GPLv2
    … …  
    265265
    266266== Changelog ==
     267= 2.10.6 - 19 Oct 2026 =
     268* Security: front-end submissions always save entries as the post type configured in the form, and never as WordPress-internal types or as forms.
     269* Security: anonymous registration cannot assign a role that can manage the site or its users. The list of blocked capabilities can be changed with the `buddyforms_registration_blocked_capabilities` filter.
     270* Security: saving a form in the form builder and saving the entry fields meta box now check a nonce and the user's permission to edit the post.
     271* Changed: the `post_type` attribute of the `[buddyforms_form]` shortcode no longer changes the post type entries are saved as. Use the `buddyforms_submission_post_type` filter instead.
     272* Fixed a fatal error when a submission arrived without an entry ID.
     273* Updated the Go Pro links to the current themekraft.com product pages.
    267274= 2.10.5 - 07 Oct 2026 =
    268275* Fixed a fatal error when activating the premium version while the free version is active. Activating one version now deactivates the other one.
  • buddyforms/trunk/vendor/composer/installed.php

    r3733032 r3780268  
    22    'root' => array(
    33        'name' => 'themekraft/buddyforms',
    4         'pretty_version' => '2.10.5',
    5         'version' => '2.10.5.0',
    6         'reference' => 'da2f8a1863648fc7eeb253a05ff2dad5e75b4672',
     4        'pretty_version' => '2.10.6',
     5        'version' => '2.10.6.0',
     6        'reference' => '55fb036638e1eb2b203df5a05e800cfee608cc65',
    77        'type' => 'wordpress-plugin',
    88        'install_path' => __DIR__ . '/../../',
    … …  
    2121        ),
    2222        'themekraft/buddyforms' => array(
    23             'pretty_version' => '2.10.5',
    24             'version' => '2.10.5.0',
    25             'reference' => 'da2f8a1863648fc7eeb253a05ff2dad5e75b4672',
     23            'pretty_version' => '2.10.6',
     24            'version' => '2.10.6.0',
     25            'reference' => '55fb036638e1eb2b203df5a05e800cfee608cc65',
    2626            'type' => 'wordpress-plugin',
    2727            'install_path' => __DIR__ . '/../../',
Note: See TracChangeset for help on using the changeset viewer.