Skip to content

Commit 75b6552

Browse files
authored
Merge pull request #890 from kprajapatii/master
Improve image validation during the cropping process - FIXED/SECURITY
2 parents c77f85d + dbad43c commit 75b6552

6 files changed

Lines changed: 57 additions & 43 deletions

File tree

includes/class-forms.php

Lines changed: 42 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -103,25 +103,24 @@ public function handler() {
103103
}
104104

105105
if ( $processed ) {
106-
107106
if ( is_wp_error( $errors ) ) {
108-
echo aui()->alert(
109-
array( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
110-
'type' => 'error',
111-
'class' => 'text-center',
112-
'content' => wp_kses_post( $errors->get_error_message() ),
113-
)
114-
);
115-
} elseif ( $redirect ) {
107+
aui()->alert(
108+
array(
109+
'type' => 'error',
110+
'content' => wp_kses_post( $errors->get_error_message() )
111+
),
112+
true
113+
);
114+
} else if ( $redirect ) {
116115
wp_safe_redirect( $redirect );
117116
exit();
118-
} else {
119-
echo aui()->alert(
120-
array( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
121-
'type' => 'success',
122-
'class' => 'text-center',
123-
'content' => wp_kses_post( $message ),
124-
)
117+
} else {
118+
aui()->alert(
119+
array(
120+
'type' => 'success',
121+
'content' => wp_kses_post( $message )
122+
),
123+
true
125124
);
126125
}
127126
}
@@ -197,6 +196,7 @@ public function process_upload_submit( $data = array(), $files = array(), $type
197196
*/
198197
public function process_image_crop( $data = array(), $type = 'avatar', $unlink_prev_img = false ) {
199198
global $wpdb;
199+
200200
if ( ! is_user_logged_in() ) {
201201
return false;
202202
}
@@ -205,6 +205,27 @@ public function process_image_crop( $data = array(), $type = 'avatar', $unlink_p
205205
return;
206206
}
207207

208+
$image_url = ! empty( $data['uwp_crop'] ) ? esc_url( $data['uwp_crop'] ) : '';
209+
210+
if ( empty( $image_url ) ) {
211+
return new WP_Error( 'empty_image', __( 'Upload valid image.', 'userswp' ) );
212+
}
213+
214+
// Ensure we have a valid URL with an allowed meme type.
215+
$image_url = $this->normalize_url( $image_url );
216+
217+
$content_url = str_replace( array( 'https://', 'http://' ) , '', untrailingslashit( WP_CONTENT_URL ) );
218+
$_image_url = str_replace( array( 'https://', 'http://' ), '', $image_url );
219+
if ( strpos( $_image_url, $content_url ) !== 0 ) {
220+
return new WP_Error( 'invalid_image', __( 'Invalid image url.', 'userswp' ) );
221+
}
222+
223+
$filetype = wp_check_filetype( $image_url );
224+
225+
if ( empty( $filetype['ext'] ) ) {
226+
return new WP_Error( 'invalid_image', __( 'Invalid image type.', 'userswp' ) );
227+
}
228+
208229
// If is current user's profile (profile.php)
209230
if ( is_admin() && defined( 'IS_PROFILE_PAGE' ) && IS_PROFILE_PAGE ) {
210231
$user_id = get_current_user_id();
@@ -216,19 +237,6 @@ public function process_image_crop( $data = array(), $type = 'avatar', $unlink_p
216237
$user_id = get_current_user_id();
217238
}
218239

219-
// Ensure we have a valid URL with an allowed meme type.
220-
$image_url = $this->normalize_url( esc_url( $data['uwp_crop'] ) );
221-
$filetype = wp_check_filetype( $image_url );
222-
223-
$errors = new WP_Error();
224-
if ( empty( $image_url ) || empty( $filetype['ext'] ) ) {
225-
$errors->add( 'something_wrong', __( 'Something went wrong. Please contact site admin.', 'userswp' ) );
226-
}
227-
228-
if ( $errors->has_errors() ) {
229-
return $errors;
230-
}
231-
232240
// Retrieve current thumbnail.
233241
$current_field = 'avatar' === $type ? 'avatar_thumb' : 'banner_thumb';
234242
$current_thumbnail = $this->normalize_url( uwp_get_usermeta( $user_id, $current_field, '' ) );
@@ -253,11 +261,12 @@ public function process_image_crop( $data = array(), $type = 'avatar', $unlink_p
253261
$name = sanitize_file_name( pathinfo( $image_path, PATHINFO_FILENAME ) ); //file name without extension
254262
$thumb_image_name = $name . $thumb_postfix . '.' . $ext;
255263
$thumb_image_location = str_replace( $name . '.' . $ext, $thumb_image_name, $image_path );
264+
256265
//Get the new coordinates to crop the image.
257-
$x = $data['x'];
258-
$y = $data['y'];
259-
$w = $data['w'];
260-
$h = $data['h'];
266+
$x = $data['uwpx'];
267+
$y = $data['uwpy'];
268+
$w = $data['uwpw'];
269+
$h = $data['uwph'];
261270
//Scale the image based on cropped width setting
262271
$scale = $full_width / $w;
263272
//$scale = 1; // no scaling

includes/class-userswp.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ public function load_forms_actions_and_filters( $instance ) {
571571

572572
// general
573573
add_action( 'init', array( $instance, 'init_notices' ), 1 );
574-
add_action( 'uwp_loaded', array( $instance, 'handler' ) );
574+
add_action( 'init', array( $instance, 'handler' ), 11 );
575575
add_action( 'init', array( $instance, 'privacy_submit_handler' ) );
576576
add_action( 'uwp_template_display_notices', array( $instance, 'display_notices' ), 10, 1 );
577577
add_action( 'wp_ajax_uwp_upload_file_remove', array( $instance, 'upload_file_remove' ) );

readme.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,9 @@ Yes, you can customize it with Elementor, but also with Gutenberg, Divi, Beaver
152152

153153
== Changelog ==
154154

155+
= 1.2.59 - 2026-03-TBD =
156+
* Improve image validation during the cropping process - FIXED/SECURITY
157+
155158
= 1.2.58 - 2026-03-26 =
156159
* UsersWP import workflow CSV import security improvement - FIXED/SECURITY
157160
* Invalid activation link for usernames that contain spaces or special characters - FIXED

templates/bootstrap/modal-profile-image-crop.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,28 +36,28 @@
3636
echo aui()->input(array( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
3737
'type' => 'hidden',
3838
'id' => esc_html( $type.'-x' ),
39-
'name' => 'x',
39+
'name' => 'uwpx',
4040
'value' => '',
4141
'no_wrap' => true,
4242
));
4343
echo aui()->input(array( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
4444
'type' => 'hidden',
4545
'id' => esc_html( $type.'-y' ),
46-
'name' => 'y',
46+
'name' => 'uwpy',
4747
'value' => '',
4848
'no_wrap' => true,
4949
));
5050
echo aui()->input(array( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
5151
'type' => 'hidden',
5252
'id' => esc_html( $type.'-w' ),
53-
'name' => 'w',
53+
'name' => 'uwpw',
5454
'value' => '',
5555
'no_wrap' => true,
5656
));
5757
echo aui()->input(array( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
5858
'type' => 'hidden',
5959
'id' => esc_html( $type.'-h' ),
60-
'name' => 'h',
60+
'name' => 'uwph',
6161
'value' => '',
6262
'no_wrap' => true,
6363
));

templates/bootstrap/profile-header.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323
return;
2424
}
2525

26-
if ( ! $uwp_in_user_loop ){ ?>
26+
if ( ! $uwp_in_user_loop ) {
27+
do_action( 'uwp_template_display_notices', 'profile' );
28+
?>
2729
<div class="card shadow-0 border-0 mw-100"><?php }
2830

2931
if ( ! $hide_cover ) {

templates/modal-profile-image-crop.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@
3434
<div class="uwp-<?php echo esc_attr( $type ); ?>-crop-p-wrap">
3535
<div id="<?php echo esc_attr( $type ); ?>-crop-actions">
3636
<form class="uwp-crop-form" method="post">
37-
<input type="hidden" name="x" value="" id="<?php echo esc_attr( $type ); ?>-x" />
38-
<input type="hidden" name="y" value="" id="<?php echo esc_attr( $type ); ?>-y" />
39-
<input type="hidden" name="w" value="" id="<?php echo esc_attr( $type ); ?>-w" />
40-
<input type="hidden" name="h" value="" id="<?php echo esc_attr( $type ); ?>-h" />
37+
<input type="hidden" name="uwpx" value="" id="<?php echo esc_attr( $type ); ?>-x" />
38+
<input type="hidden" name="uwpy" value="" id="<?php echo esc_attr( $type ); ?>-y" />
39+
<input type="hidden" name="uwpw" value="" id="<?php echo esc_attr( $type ); ?>-w" />
40+
<input type="hidden" name="uwph" value="" id="<?php echo esc_attr( $type ); ?>-h" />
4141
<input type="hidden" id="uwp-<?php echo esc_attr( $type ); ?>-crop-image" name="uwp_crop" value="<?php echo esc_attr( $image_url ); ?>" />
4242
<input type="hidden" name="uwp_crop_nonce" value="<?php echo esc_attr( wp_create_nonce( 'uwp_crop_nonce_'.$type ) ); ?>" />
4343
<input type="submit" name="uwp_<?php echo esc_attr( $type ); ?>_crop" value="<?php esc_attr_e('Apply', 'userswp'); ?>" class="button button-primary" id="save_uwp_<?php echo esc_attr( $type ); ?>" />

0 commit comments

Comments
 (0)