Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions includes/Admin/Admin_Tools.php
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@
* @return bool
*/
public static function import_json_file( $file ) {
$encode_data = file_get_contents( $file );

Check warning on line 181 in includes/Admin/Admin_Tools.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

file_get_contents() is discouraged. Use wp_remote_get() for remote URLs instead.
$options = json_decode( $encode_data, true );

$errors = new WP_Error();
Expand Down Expand Up @@ -222,7 +222,7 @@
public function export_forms( $form_type, $export_type, $form_ids ) {
if ( $export_type === 'all' ) {
static::export_to_json( $form_type );
} else if ( 'selected' === $export_type ) {

Check warning on line 225 in includes/Admin/Admin_Tools.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Usage of ELSE IF is discouraged; use ELSEIF instead
if ( empty( $form_ids ) ) {
printf(
'<div class="error"><p>%s</p></div>',
Expand All @@ -247,7 +247,7 @@
$date = date( 'Y-m-d' ); // phpcs:ignore
$json_name = $blogname . '-wpuf-' . $post_type . '-' . $date; // Namming the filename will be generated.

if ( !empty( $post_ids ) ) {

Check failure on line 250 in includes/Admin/Admin_Tools.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Expected 1 space after "!"; 0 found
foreach ( $post_ids as $key => $value ) {
array_push( $ids, $value );
}
Expand All @@ -256,7 +256,7 @@
$args = [
'post_status' => 'publish',
'post_type' => $post_type,
'post__in' => ( !empty( $ids ) ) ? $ids : '',

Check failure on line 259 in includes/Admin/Admin_Tools.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Expected 1 space after "!"; 0 found
];

$query = new WP_Query( $args );
Expand Down Expand Up @@ -296,18 +296,18 @@
*
* @return array
*/
public function formetted_meta_key_value( $array ) {

Check warning on line 299 in includes/Admin/Admin_Tools.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

It is recommended not to use reserved keyword "array" as function parameter name. Found: $array
$result = [ ];

Check failure on line 300 in includes/Admin/Admin_Tools.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

There should be no space between the array opener and closer for an empty array. Found: 1 space

foreach ( $array as $key => $val ) {
$result[$key] = $val[0];

Check failure on line 303 in includes/Admin/Admin_Tools.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Array keys must be surrounded by spaces unless they contain a string or an integer.
}

return $result;
}

public function tool_page() {
$msg = isset( $_GET['msg'] ) ? sanitize_text_field( wp_unslash( $_GET['msg'] ) ) : '';

Check warning on line 310 in includes/Admin/Admin_Tools.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Processing form data without nonce verification.

Check warning on line 310 in includes/Admin/Admin_Tools.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Processing form data without nonce verification.
$text = '';
$confirmation_message = __( 'Are you Sure?', 'wp-user-frontend' );
switch ( $msg ) {
Expand Down Expand Up @@ -456,6 +456,18 @@
*/
public function import_forms() {
check_ajax_referer( 'wpuf_admin_tools' );

// Security: Check user has proper admin capabilities
if ( ! current_user_can( wpuf_admin_role() ) ) {
wp_send_json_error(
new WP_Error(
'wpuf_ajax_import_forms_error',
__( 'Unauthorized operation', 'wp-user-frontend' )
),
WP_Http::FORBIDDEN
);
}

if ( ! isset( $_POST['file_id'] ) ) {
wp_send_json_error(
new WP_Error(
Expand Down
7 changes: 7 additions & 0 deletions includes/Ajax/Admin_Form_Builder_Ajax.php
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,13 @@ class="tax-list-selector wpuf-w-full wpuf-mt-2 wpuf-border-primary">';
}

public function get_roles() {
// Security: Check nonce and user capabilities
check_ajax_referer( 'wpuf-form-builder' );

if ( ! current_user_can( wpuf_admin_role() ) ) {
wp_send_json_error( __( 'Unauthorized operation', 'wp-user-frontend' ) );
}

$roles = wpuf_get_user_roles();

$html = '<div class="wpuf-mt-6 wpuf-input-container"><div class="wpuf-flex wpuf-items-center"><label for="default_category" class="wpuf-text-sm wpuf-text-gray-700 wpuf-my-2">' . __( 'Choose who can submit post ', 'wp-user-frontend' ) . '</label></div>';
Expand Down
22 changes: 19 additions & 3 deletions includes/Ajax/Frontend_Form_Ajax.php
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,9 @@ public function submit_post() {
'post_type' => ! empty( $this->form_settings['post_type'] ) ? $this->form_settings['post_type'] : 'post',
'post_status' => isset( $this->form_settings['post_status'] ) ? $this->form_settings['post_status'] : 'publish',
'post_author' => $post_author,
'post_title' => isset( $_POST['post_title'] ) ? sanitize_text_field( wp_unslash( $_POST['post_title'] ) ) : '',
'post_content' => isset( $_POST['post_content'] ) ? wp_kses( wp_unslash( $_POST['post_content'] ), $allowed_tags ) : '',
'post_excerpt' => isset( $_POST['post_excerpt'] ) ? wp_kses( wp_unslash( $_POST['post_excerpt'] ), $allowed_tags ) : '',
'post_title' => isset( $_POST['post_title'] ) ? strip_shortcodes( sanitize_text_field( wp_unslash( $_POST['post_title'] ) ) ) : '',
'post_content' => isset( $_POST['post_content'] ) ? strip_shortcodes( wp_kses( wp_unslash( $_POST['post_content'] ), $allowed_tags ) ) : '',
'post_excerpt' => isset( $_POST['post_excerpt'] ) ? strip_shortcodes( wp_kses( wp_unslash( $_POST['post_excerpt'] ), $allowed_tags ) ) : '',
];

// $charging_enabled = wpuf_get_option( 'charge_posting', 'wpuf_payment' );
Expand Down Expand Up @@ -228,6 +228,22 @@ public function submit_post() {
// if post_id is passed, we update the post
if ( isset( $_POST['post_id'] ) ) {
$post_id = intval( wp_unslash( $_POST['post_id'] ) );

// Verify the post exists
$post = get_post( $post_id );
if ( ! $post || is_wp_error( $post ) ) {
wpuf()->ajax->send_error( __( 'Post not found.', 'wp-user-frontend' ) );
}

// Security: Check if user has permission to edit this post (Broken Access Control fix)
$post_author = (int) get_post_field( 'post_author', $post_id );
$current_user_id = get_current_user_id();

// Allow edit if: user is post author OR user has edit_others_posts capability
if ( $current_user_id !== $post_author && ! current_user_can( 'edit_others_posts' ) ) {
wpuf()->ajax->send_error( __( 'You do not have permission to edit this post.', 'wp-user-frontend' ) );
}

$is_update = true;
$postarr['ID'] = $post_id;
$postarr['post_date'] = isset( $_POST['post_date'] ) ? sanitize_text_field( wp_unslash( $_POST['post_date'] ) ) : '';
Expand Down
2 changes: 1 addition & 1 deletion includes/Fields/Field_Contract.php
Original file line number Diff line number Diff line change
Expand Up @@ -871,7 +871,7 @@ public function conditional_logic( $form_field, $form_id ) {
public function prepare_entry( $field ) {
check_ajax_referer( 'wpuf_form_add' );

$value = ! empty( $_POST[ $field['name'] ] ) ? sanitize_text_field( wp_unslash( $_POST[ $field['name'] ] ) ) :
$value = ! empty( $_POST[ $field['name'] ] ) ? strip_shortcodes( sanitize_text_field( wp_unslash( $_POST[ $field['name'] ] ) ) ) :
'';

if ( is_array( $value ) ) {
Expand Down
1 change: 1 addition & 0 deletions includes/Fields/Form_Field_Checkbox.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@
* @return void
*/
public function render( $field_settings, $form_id, $type = 'post', $post_id = null ) {
if ( isset( $post_id ) && $post_id != '0' ) {

Check warning on line 27 in includes/Fields/Form_Field_Checkbox.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Loose comparisons are not allowed. Expected: "!=="; Found: "!="

Check failure on line 27 in includes/Fields/Form_Field_Checkbox.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Expected exactly one space before closing parenthesis; " " found.
if ( $this->is_meta( $field_settings ) ) {
if ( $value = $this->get_meta( $post_id, $field_settings['name'], $type, true ) ) {

Check failure on line 29 in includes/Fields/Form_Field_Checkbox.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Assignments must be the first block of code on a line

Check warning on line 29 in includes/Fields/Form_Field_Checkbox.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Variable assignment found within a condition. Did you mean to do a comparison ?
$selected = $this->get_formatted_value( $value );
} else {
$selected = [];
Expand All @@ -43,13 +43,13 @@
if ( $field_settings['options'] && count( $field_settings['options'] ) > 0 ) {
foreach ( $field_settings['options'] as $value => $option ) {
?>
<label <?php echo esc_attr( $field_settings['inline'] ) == 'yes' ? 'class="wpuf-checkbox-inline"' : 'class="wpuf-checkbox-block"'; ?>>

Check warning on line 46 in includes/Fields/Form_Field_Checkbox.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Loose comparisons are not allowed. Expected: "==="; Found: "=="
<input
type="checkbox"
class="<?php echo esc_attr( sprintf( 'wpuf_%s_%d', $field_settings['name'], $form_id ) ); ?>"
id="<?php echo esc_attr( $field_settings['name'] ); ?>"
name="<?php echo esc_attr( $field_settings['name'] ); ?>[]"
value="<?php echo esc_attr( $value ); ?>"<?php echo in_array( $value, $selected ) ? ' checked="checked"' : ''; ?>

Check failure on line 52 in includes/Fields/Form_Field_Checkbox.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Not using strict comparison for in_array; supply true for $strict argument.
data-required="<?php echo esc_attr( $field_settings['required'] ); ?>"
data-type="checkbox"
/>
Expand All @@ -57,13 +57,13 @@
</label>
<?php
}
} ?>

Check failure on line 60 in includes/Fields/Form_Field_Checkbox.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Closing PHP tag must be on a line by itself

<?php $this->help_text( $field_settings ); ?>

</div>

<?php $this->after_field_print_label();

Check failure on line 66 in includes/Fields/Form_Field_Checkbox.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Opening PHP tag must be on a line by itself
}

/**
Expand All @@ -72,7 +72,7 @@
* @return array
*/
public function get_options_settings() {
$default_options = $this->get_default_option_settings();

Check warning on line 75 in includes/Fields/Form_Field_Checkbox.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Equals sign not aligned correctly; expected 1 space but found 2 spaces

$dropdown_options = [
$this->get_default_option_dropdown_settings( true ),
Expand Down Expand Up @@ -104,7 +104,7 @@
public function get_field_props() {
$defaults = $this->default_attributes();

$props = [

Check warning on line 107 in includes/Fields/Form_Field_Checkbox.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Equals sign not aligned correctly; expected 1 space but found 4 spaces
'input_type' => 'checkbox',
'is_meta' => 'yes',
'selected' => [],
Expand All @@ -129,7 +129,8 @@
public function prepare_entry( $field ) {
check_ajax_referer( 'wpuf_form_add' );

$field_name = isset( $_POST[$field['name']] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST[$field['name']] ) ) : [];

Check failure on line 132 in includes/Fields/Form_Field_Checkbox.php

View workflow job for this annotation

GitHub Actions / Run PHPCS inspection

Array keys must be surrounded by spaces unless they contain a string or an integer.
$field_name = array_map( 'sanitize_text_field', array_map( 'strip_shortcodes', $field_name ) );

$entry_value = ( is_array( $field_name ) && $field_name ) ? $field_name : [];

Expand Down
2 changes: 1 addition & 1 deletion includes/Fields/Form_Field_Dropdown.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ public function get_field_props() {
public function prepare_entry( $field ) {
check_ajax_referer( 'wpuf_form_add' );

$val = isset( $_POST[$field['name']] ) ? sanitize_text_field( wp_unslash( $_POST[$field['name']] ) ) : '';
$val = isset( $_POST[$field['name']] ) ? strip_shortcodes( sanitize_text_field( wp_unslash( $_POST[$field['name']] ) ) ) : '';

return isset( $field['options'][$val] ) ? $field['options'][$val] : '';
}
Expand Down
2 changes: 1 addition & 1 deletion includes/Fields/Form_Field_Email.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public function prepare_entry( $field ) {
return $user->user_email;
}
}
$value = !empty( $_POST[$field['name']] ) ? sanitize_text_field( wp_unslash( $_POST[$field['name']] ) ) : '';
$value = !empty( $_POST[$field['name']] ) ? strip_shortcodes( sanitize_text_field( wp_unslash( $_POST[$field['name']] ) ) ) : '';

return sanitize_text_field( trim( $value ) );
}
Expand Down
1 change: 1 addition & 0 deletions includes/Fields/Form_Field_MultiDropdown.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ public function prepare_entry( $field ) {
check_ajax_referer( 'wpuf_form_add' );

$field_name = isset( $_POST[$field['name']] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST[$field['name']] ) ) : [];
$field_name = array_map( 'strip_shortcodes', $field_name );
$entry_value = ( is_array( $field_name ) && $field_name ) ? $field_name : [];

if ( $entry_value ) {
Expand Down
2 changes: 1 addition & 1 deletion includes/Fields/Form_Field_Post_Content.php
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ public function get_field_props() {
public function prepare_entry( $field ) {
check_ajax_referer( 'wpuf_form_add' );

$field = isset( $_POST[ $field['name'] ] ) ? sanitize_text_field( wp_unslash( $_POST[ $field['name'] ] ) ) : '';
$field = isset( $_POST[ $field['name'] ] ) ? strip_shortcodes( sanitize_text_field( wp_unslash( $_POST[ $field['name'] ] ) ) ) : '';

return trim( $field );
}
Expand Down
2 changes: 1 addition & 1 deletion includes/Fields/Form_Field_Post_Excerpt.php
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ public function get_field_props() {
public function prepare_entry( $field ) {
check_ajax_referer( 'wpuf_form_add' );

$field = isset( $_POST[ $field['name'] ] ) ? sanitize_text_field( wp_unslash( $_POST[ $field['name'] ] ) ) : '';
$field = isset( $_POST[ $field['name'] ] ) ? strip_shortcodes( sanitize_text_field( wp_unslash( $_POST[ $field['name'] ] ) ) ) : '';

return wp_kses_post( $field );
Comment on lines +154 to 156
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Incorrect sanitization breaks rich text editing.

The use of sanitize_text_field() strips all HTML tags and line breaks, then wp_kses_post() becomes redundant. This breaks the rich text editing functionality supported by this field (see render method lines 41-87 where wp_editor is used for rich/teeny modes). WordPress post excerpts typically allow basic HTML formatting.

Apply this diff to fix the sanitization order while preserving the shortcode stripping security fix:

-        $field = isset( $_POST[ $field['name'] ] ) ? strip_shortcodes( sanitize_text_field( wp_unslash( $_POST[ $field['name'] ] ) ) ) : '';
+        $field = isset( $_POST[ $field['name'] ] ) ? wp_kses_post( strip_shortcodes( wp_unslash( $_POST[ $field['name'] ] ) ) ) : '';
 
-        return wp_kses_post( $field );
+        return $field;

This approach:

  • Removes slashes with wp_unslash()
  • Strips shortcodes for security
  • Sanitizes HTML with wp_kses_post() to allow post-content tags
  • Eliminates the redundant second wp_kses_post() call
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
$field = isset( $_POST[ $field['name'] ] ) ? strip_shortcodes( sanitize_text_field( wp_unslash( $_POST[ $field['name'] ] ) ) ) : '';
return wp_kses_post( $field );
$field = isset( $_POST[ $field['name'] ] )
? wp_kses_post( strip_shortcodes( wp_unslash( $_POST[ $field['name'] ] ) ) )
: '';
return $field;
🤖 Prompt for AI Agents
In includes/Fields/Form_Field_Post_Excerpt.php around lines 154 to 156, the
current sanitization uses sanitize_text_field which strips HTML and makes the
later wp_kses_post redundant, breaking the wp_editor rich text; replace the
pipeline to first wp_unslash($_POST[$field['name']] ?? ''), then
strip_shortcodes on that value, then pass the result through wp_kses_post to
allow valid post HTML, and return that single wp_kses_post result (remove
sanitize_text_field and the redundant second wp_kses_post call).

}
Expand Down
2 changes: 1 addition & 1 deletion includes/Fields/Form_Field_Post_Tags.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public function get_field_props() {
public function prepare_entry( $field ) {
check_ajax_referer( 'wpuf_form_add' );

$field = isset( $_POST[$field['name']] ) ? sanitize_text_field( wp_unslash( $_POST[$field['name']] ) ) : '';
$field = isset( $_POST[$field['name']] ) ? strip_shortcodes( sanitize_text_field( wp_unslash( $_POST[$field['name']] ) ) ) : '';
return $field;
}
}
2 changes: 1 addition & 1 deletion includes/Fields/Form_Field_Post_Taxonomy.php
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ public function prepare_entry( $field ) {
// return sanitize_text_field($_POST[$field['name']]);
check_ajax_referer( 'wpuf_form_add' );

$val = isset( $_POST[ $field['name'] ] ) ? sanitize_text_field( wp_unslash( $_POST[ $field['name'] ] ) ) : '';
$val = isset( $_POST[ $field['name'] ] ) ? strip_shortcodes( sanitize_text_field( wp_unslash( $_POST[ $field['name'] ] ) ) ) : '';

return isset( $field['options'][ $val ] ) ? $field['options'][ $val ] : '';
}
Expand Down
2 changes: 1 addition & 1 deletion includes/Fields/Form_Field_Post_Title.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public function get_field_props() {
public function prepare_entry( $field ) {
check_ajax_referer( 'wpuf_form_add' );

$field = isset( $_POST[ $field['name'] ] ) ? sanitize_text_field( wp_unslash( $_POST[ $field['name'] ] ) ) : '';
$field = isset( $_POST[ $field['name'] ] ) ? strip_shortcodes( sanitize_text_field( wp_unslash( $_POST[ $field['name'] ] ) ) ) : '';
return $field;
}
}
2 changes: 1 addition & 1 deletion includes/Fields/Form_Field_Radio.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ public function get_field_props() {
public function prepare_entry( $field ) {
check_ajax_referer( 'wpuf_form_add' );

$val = isset( $_POST[$field['name']] ) ? sanitize_text_field( wp_unslash( $_POST[$field['name']] ) ) : '';
$val = isset( $_POST[$field['name']] ) ? strip_shortcodes( sanitize_text_field( wp_unslash( $_POST[$field['name']] ) ) ) : '';

return isset( $field['options'][$val] ) ? $field['options'][$val] : '';
}
Expand Down
2 changes: 1 addition & 1 deletion includes/Fields/Form_Field_Text.php
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ public function get_field_props() {
public function prepare_entry( $field ) {
check_ajax_referer( 'wpuf_form_add' );

$value = isset( $_POST[ $field['name'] ] ) ? sanitize_text_field( wp_unslash( $_POST[ $field['name'] ] ) ) : '';
$value = isset( $_POST[ $field['name'] ] ) ? strip_shortcodes( sanitize_text_field( wp_unslash( $_POST[ $field['name'] ] ) ) ) : '';
// return sanitize_text_field( trim( $_POST[$field['name']] ) );
return $value;
}
Comment on lines 152 to 158
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Security fix correctly implements shortcode stripping.

The addition of strip_shortcodes() in the sanitization chain effectively prevents arbitrary shortcode execution via user-submitted text fields. The order of operations is correct:

  1. wp_unslash() removes WordPress slashes
  2. sanitize_text_field() sanitizes input and encodes special characters
  3. strip_shortcodes() removes any shortcode patterns as a final safeguard

Combined with the nonce check on line 153, this provides defense-in-depth against shortcode injection attacks.

Run the following script to verify this pattern has been consistently applied across all field types mentioned in the AI summary:


🏁 Script executed:

#!/bin/bash
# Description: Verify strip_shortcodes is consistently applied in prepare_entry methods

# Search for prepare_entry methods that handle POST data
rg -n -A 5 'function prepare_entry' --type=php -g 'includes/Fields/*.php' | \
  rg -C 3 '\$_POST'

Length of output: 8468


Add missing shortcode stripping in taxonomy field sanitization

includes/Fields/Form_Field_Post_Taxonomy.php (lines 520–525): wrap the POST value with wp_unslash()sanitize_text_field()strip_shortcodes() before use, e.g.:

$value = isset($_POST[$field['name']])
    ? strip_shortcodes(sanitize_text_field(wp_unslash($_POST[$field['name']])))
    : '';
🤖 Prompt for AI Agents
In includes/Fields/Form_Field_Text.php around lines 152 to 158, the field value
is sanitized but not consistently stripped of shortcodes; update the POST value
handling to mirror the suggested pattern used elsewhere by wrapping the raw POST
value with wp_unslash(), then sanitize_text_field(), then strip_shortcodes()
before returning (i.e., $value = isset($_POST[$field['name']]) ?
strip_shortcodes(sanitize_text_field(wp_unslash($_POST[$field['name']]))) :
'';), preserving the existing check_ajax_referer() call and return behavior.

Expand Down
6 changes: 3 additions & 3 deletions includes/Fields/Form_Field_Textarea.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ public function get_field_props() {
public function prepare_entry( $field ) {
check_ajax_referer( 'wpuf_form_add' );

$field = isset( $_POST[ $field['name'] ] ) ? sanitize_text_field( wp_unslash( $_POST[ $field['name'] ] ) ) : '';
$field = isset( $_POST[ $field['name'] ] ) ? strip_shortcodes( sanitize_text_field( wp_unslash( $_POST[ $field['name'] ] ) ) ) : '';
return trim( $field );
}

Expand Down Expand Up @@ -189,7 +189,7 @@ public function render_field_data( $data, $field ) {
<?php if ( ! $hide_label ) : ?>
<label><?php echo esc_html( $field['label'] ); ?>:</label>
<?php endif; ?>
<?php echo wp_kses_post( wpautop( make_clickable( $data ) ) ); ?>
<?php echo wp_kses_post( wpautop( make_clickable( strip_shortcodes( $data ) ) ) ); ?>
</li>
<?php
return ob_get_clean();
Expand All @@ -206,6 +206,6 @@ public function render_field_data( $data, $field ) {
* @return string
*/
public function sanitize_field_data( $data, $field ) {
return wp_kses_post( $data );
return strip_shortcodes( wp_kses_post( $data ) );
}
}
2 changes: 1 addition & 1 deletion includes/Fields/Form_Field_URL.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public function get_field_props() {
public function prepare_entry( $field ) {
check_ajax_referer( 'wpuf_form_add' );

$field = isset( $_POST[ $field['name'] ] ) ? sanitize_text_field( wp_unslash( $_POST[ $field['name'] ] ) ) : '';
$field = isset( $_POST[ $field['name'] ] ) ? strip_shortcodes( sanitize_text_field( wp_unslash( $_POST[ $field['name'] ] ) ) ) : '';
return esc_url( trim( $field ) );
}

Expand Down
29 changes: 18 additions & 11 deletions includes/Frontend/Form_Preview.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,14 @@ public function __construct() {
if ( ! isset( $_GET['wpuf_preview'] ) && empty( $_GET['wpuf'] ) ) {
return;
}
$this->form_id = isset( $_GET['form_id'] ) ? intval( $_GET['form_id'] ) : 0;

// Security: Check user has proper capabilities before allowing preview
if ( ! is_user_logged_in() || ! current_user_can( wpuf_admin_role() ) ) {
wp_die( __( 'You do not have permission to preview this form.', 'wp-user-frontend' ), 403 );
}

// Security: Validate and sanitize form_id parameter
$this->form_id = isset( $_GET['form_id'] ) ? absint( $_GET['form_id'] ) : 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

recheck nonce verification

add_action( 'pre_get_posts', [ $this, 'pre_get_posts' ] );
// add_filter( 'template_include', [ $this, 'template_include' ] );
add_filter( 'the_title', [ $this, 'the_title' ] );
Expand Down Expand Up @@ -77,18 +84,18 @@ public function the_title( $title ) {
* @return string
*/
public function the_content( $content ) {
if ( $this->is_preview ) {
if ( ! is_user_logged_in() ) {
return __( 'You must be logged in to preview this form.', 'wp-user-frontend' );
}
$viewing_capability = apply_filters( 'wpuf_preview_form_cap',
'edit_posts' ); // at least has to be contributor
if ( ! current_user_can( $viewing_capability ) ) {
return __( 'Sorry, you are not eligible to preview this form.', 'wp-user-frontend' );
}
// Security: Double-check admin capabilities
if ( ! current_user_can( wpuf_admin_role() ) ) {
return __( 'You do not have permission to preview this form.', 'wp-user-frontend' );
}

// Security: Validate form_id is a valid integer to prevent injection
$form_id = absint( $this->form_id );
if ( $form_id === 0 ) {
return __( 'Invalid form ID.', 'wp-user-frontend' );
}

return do_shortcode( sprintf( '[wpuf_form id="%d"]', $this->form_id ) );
return do_shortcode( sprintf( '[wpuf_form id="%d"]', $form_id ) );
}

/**
Expand Down
5 changes: 5 additions & 0 deletions includes/Frontend_Render_Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@ public function guest_fields( $form_settings ) {
* @return void
*/
public function preview_form() {
// Security: Check user has proper admin capabilities
if ( ! current_user_can( wpuf_admin_role() ) ) {
wp_send_json_error( __( 'Unauthorized operation', 'wp-user-frontend' ) );
}

$form_id = isset( $_GET['form_id'] ) ? intval( wp_unslash( $_GET['form_id'] ) ) : 0;

if ( $form_id ) {
Expand Down
10 changes: 5 additions & 5 deletions includes/Traits/FieldableTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -589,9 +589,9 @@ public static function prepare_meta_fields( $meta_vars ) {
$meta_key_value[ $value['name'] ] = $wpuf_field->sanitize_field_data( $posted_field_data, $value );
continue;
} elseif ( isset( $post_data[ $value['name'] ] ) && is_array( $post_data[ $value['name'] ] ) ) {
$value_name = isset( $post_data[ $value['name'] ] ) ? array_map( 'sanitize_text_field', wp_unslash( $post_data[ $value['name'] ] ) ) : '';
$value_name = isset( $post_data[ $value['name'] ] ) ? array_map( function( $item ) { return strip_shortcodes( sanitize_text_field( $item ) ); }, wp_unslash( $post_data[ $value['name'] ] ) ) : '';
} else {
$value_name = isset( $post_data[ $value['name'] ] ) ? sanitize_text_field( wp_unslash( $post_data[ $value['name'] ] ) ) : '';
$value_name = isset( $post_data[ $value['name'] ] ) ? strip_shortcodes( sanitize_text_field( wp_unslash( $post_data[ $value['name'] ] ) ) ) : '';
}

if ( isset( $post_data['wpuf_files'][ $value['name'] ] ) ) {
Expand Down Expand Up @@ -635,13 +635,13 @@ public static function prepare_meta_fields( $meta_vars ) {
if ( in_array( $inner_field['template'], [ 'checkbox_field', 'multiple_select' ] ) ) {
// For checkbox and multiselect, keep as array and sanitize each element
if ( is_array( $row[ $fname ] ) ) {
$sanitized_row[ $fname ] = array_map( 'sanitize_text_field', $row[ $fname ] );
$sanitized_row[ $fname ] = array_map( function( $item ) { return strip_shortcodes( sanitize_text_field( $item ) ); }, $row[ $fname ] );
} else {
$sanitized_row[ $fname ] = sanitize_text_field( $row[ $fname ] );
$sanitized_row[ $fname ] = strip_shortcodes( sanitize_text_field( $row[ $fname ] ) );
}
} else {
// For other fields, sanitize as string
$sanitized_row[ $fname ] = sanitize_text_field( $row[ $fname ] );
$sanitized_row[ $fname ] = strip_shortcodes( sanitize_text_field( $row[ $fname ] ) );
}
} else {
$sanitized_row[ $fname ] = '';
Expand Down
Loading
Loading