diff --git a/README.md b/README.md index 138e3f934..dfd1d7a27 100644 --- a/README.md +++ b/README.md @@ -147,6 +147,13 @@ https://www.youtube.com/watch?v=dJrykKQGDcs ## Changelog ## +### 4.7.15 + +* FIXED + * Fixed media ownership verification for activity updates with attached media. + * Fixed media ownership verification for comments on activities and single media. + * Fixed activity ownership verification and input sanitization on media upload endpoint. + ### 4.7.14 * FIXED diff --git a/app/main/controllers/activity/RTMediaBuddyPressActivity.php b/app/main/controllers/activity/RTMediaBuddyPressActivity.php index 1b0aa8693..d48930f30 100644 --- a/app/main/controllers/activity/RTMediaBuddyPressActivity.php +++ b/app/main/controllers/activity/RTMediaBuddyPressActivity.php @@ -506,7 +506,7 @@ public function bp_activity_content_before_save( $content, $class_obj ) { } $rtmedia_attached_files = filter_input( INPUT_POST, 'rtMedia_attached_files', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY ); - if ( ( ! empty( $rtmedia_attached_files ) ) && is_array( $rtmedia_attached_files ) ) { + if ( ( ! empty( $rtmedia_attached_files ) ) && is_array( $rtmedia_attached_files ) && rtmedia_is_media_owner( $rtmedia_attached_files ) ) { $obj_activity = new RTMediaActivity( $rtmedia_attached_files, 0, $content ); // Remove action to fix duplication issue of comment content. @@ -575,7 +575,7 @@ public function comment_sync( $comment_id, $param ) { // has media in comment. $rtmedia_attached_files = filter_input( INPUT_POST, 'rtMedia_attached_files', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY ); // if the media is not empty. - if ( is_array( $rtmedia_attached_files ) && ! empty( $rtmedia_attached_files[0] ) && class_exists( 'RTMediaActivity' ) ) { + if ( is_array( $rtmedia_attached_files ) && ! empty( $rtmedia_attached_files ) && class_exists( 'RTMediaActivity' ) && rtmedia_is_media_owner( $rtmedia_attached_files, $user_id ) ) { // create new html for comment content. $obj_comment = new RTMediaActivity( $rtmedia_attached_files[0], 0, $param['content'] ); $param['content'] = $obj_comment->create_activity_html( 'comment-media' ); @@ -622,13 +622,13 @@ public function bp_activity_posted_update( $content, $user_id, $activity_id ) { do_action( 'rtmedia_bp_before_activity_posted', $content, $user_id, $activity_id ); $rtmedia_attached_files = filter_input( INPUT_POST, 'rtMedia_attached_files', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY ); - if ( is_array( $rtmedia_attached_files ) ) { + if ( is_array( $rtmedia_attached_files ) && ! empty( $rtmedia_attached_files ) ) { bp_activity_update_meta( $activity_id, 'bp_activity_text', bp_activity_filter_kses( $content ) ); $media_obj = new RTMediaModel(); // Credit faisal : https://gist.github.com/faishal/c4306ae7267fff976465. $in_str_arr = array_fill( 0, count( $rtmedia_attached_files ), '%d' ); $in_str = join( ',', $in_str_arr ); - $sql = $wpdb->prepare( "update {$media_obj->table_name} set activity_id = %d where blog_id = %d and ", $activity_id, get_current_blog_id() ); // phpcs:ignore + $sql = $wpdb->prepare( "update {$media_obj->table_name} set activity_id = %d where blog_id = %d and media_author = %d and ", $activity_id, get_current_blog_id(), $user_id ); // phpcs:ignore $form_id_where = $wpdb->prepare( "id IN ($in_str)", $rtmedia_attached_files ); // phpcs:ignore $sql .= $form_id_where; $wpdb->query( $sql ); // phpcs:ignore @@ -1226,7 +1226,7 @@ public function activity_after_media_comment( $params ) { $rtmedia_attached_files = filter_input( INPUT_POST, 'rtMedia_attached_files', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY ); // check media should be in array format and is not empty to. - if ( ! empty( $rtmedia_attached_files ) && class_exists( 'RTMediaActivity' ) && is_array( $rtmedia_attached_files ) ) { + if ( ! empty( $rtmedia_attached_files ) && class_exists( 'RTMediaActivity' ) && is_array( $rtmedia_attached_files ) && rtmedia_is_media_owner( $rtmedia_attached_files, $user_id ) ) { $comment_media = true; $comment_media_id = $rtmedia_attached_files[0]; $obj_comment = new RTMediaActivity( $rtmedia_attached_files[0], 0, $comment_content ); diff --git a/app/main/controllers/media/RTMediaComment.php b/app/main/controllers/media/RTMediaComment.php index 1132b4d1d..c9862145f 100755 --- a/app/main/controllers/media/RTMediaComment.php +++ b/app/main/controllers/media/RTMediaComment.php @@ -100,7 +100,7 @@ public function add( $attr ) { $rtmedia_attached_files = filter_input( INPUT_POST, 'rtMedia_attached_files', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY ); // add comment id in the rtmedia meta fields. - if ( ! empty( $rtmedia_attached_files ) && is_array( $rtmedia_attached_files ) ) { + if ( ! empty( $rtmedia_attached_files ) && is_array( $rtmedia_attached_files ) && function_exists( 'rtmedia_is_media_owner' ) && rtmedia_is_media_owner( $rtmedia_attached_files ) ) { add_rtmedia_meta( $rtmedia_attached_files[0], 'rtmedia_comment_media_comment_id', $id ); } diff --git a/app/main/controllers/template/RTMediaTemplate.php b/app/main/controllers/template/RTMediaTemplate.php index c058aee2f..37f447c14 100755 --- a/app/main/controllers/template/RTMediaTemplate.php +++ b/app/main/controllers/template/RTMediaTemplate.php @@ -894,12 +894,17 @@ public function check_return_comments() { } if ( ! empty( $rtmedia_attached_files ) ) { - // has media. - $comment_with_media = true; - - // create new html for comment content. - $obj_comment = new RTMediaActivity( $rtmedia_attached_files[0], 0, $comment_content ); - $comment_content = $obj_comment->create_activity_html( 'comment-media' ); + if ( rtmedia_is_media_owner( $rtmedia_attached_files ) ) { + // has media. + $comment_with_media = true; + + // create new html for comment content. + $obj_comment = new RTMediaActivity( $rtmedia_attached_files[0], 0, $comment_content ); + $comment_content = $obj_comment->create_activity_html( 'comment-media' ); + } else { + unset( $_POST['rtMedia_attached_files'] ); + $rtmedia_attached_files = array(); + } } $comment = new RTMediaComment(); diff --git a/app/main/controllers/template/rtmedia-ajax-actions.php b/app/main/controllers/template/rtmedia-ajax-actions.php index 0bc651303..6034e39b9 100644 --- a/app/main/controllers/template/rtmedia-ajax-actions.php +++ b/app/main/controllers/template/rtmedia-ajax-actions.php @@ -214,24 +214,25 @@ function rtmedia_bp_activity_after_save_callback( $activity_data ) { // check if class exits or not and it has any media in it. if ( ! empty( $rtmedia_attached_files ) && isset( $activity_data->id ) && is_array( $rtmedia_attached_files ) && ! empty( $rtmedia_attached_files[0] ) && class_exists( 'RTMediaModel' ) ) { + if ( rtmedia_is_media_owner( $rtmedia_attached_files ) ) { + if ( function_exists( 'rtmedia_get_original_comment_media_content' ) ) { + // get the original content of media. + $original_content = rtmedia_get_original_comment_media_content(); + // save the original content in the meta fields. + bp_activity_update_meta( $activity_data->id, 'bp_activity_text', $original_content ); + } - if ( function_exists( 'rtmedia_get_original_comment_media_content' ) ) { - // get the original content of media. - $original_content = rtmedia_get_original_comment_media_content(); - // save the original content in the meta fields. - bp_activity_update_meta( $activity_data->id, 'bp_activity_text', $original_content ); + $rtmedia_model = new RTMediaModel(); + $rtmedia_model->update( + array( + 'activity_id' => $activity_data->id, + ), + array( + 'id' => $rtmedia_attached_files[0], + ) + ); } - $rtmedia_model = new RTMediaModel(); - $rtmedia_model->update( - array( - 'activity_id' => $activity_data->id, - ), - array( - 'id' => $rtmedia_attached_files[0], - ) - ); - $privacy = -1; $form_id = filter_input( INPUT_POST, 'form_id', FILTER_SANITIZE_NUMBER_INT ); @@ -289,7 +290,7 @@ function rtmedia_bp_activity_comment_content_callback( $content ) { if ( ! empty( $rtmedia_attached_files ) && ! empty( $comment_id ) && ! empty( $form_id ) ) { - if ( ! empty( $rtmedia_attached_files[0] ) && is_array( $rtmedia_attached_files ) && class_exists( 'RTMediaActivity' ) ) { + if ( ! empty( $rtmedia_attached_files[0] ) && is_array( $rtmedia_attached_files ) && class_exists( 'RTMediaActivity' ) && rtmedia_is_media_owner( $rtmedia_attached_files ) ) { $obj_comment = new RTMediaActivity( $rtmedia_attached_files[0], 0, $content ); $new_content = $obj_comment->create_activity_html(); } diff --git a/app/main/controllers/template/rtmedia-functions.php b/app/main/controllers/template/rtmedia-functions.php index 9261f87c1..623761ed3 100644 --- a/app/main/controllers/template/rtmedia-functions.php +++ b/app/main/controllers/template/rtmedia-functions.php @@ -5394,3 +5394,47 @@ function rtmedia_like_eraser( $email_address, $page = 1 ) { 'done' => $done, ); } + +/** + * Check if the given user owns the specified media. + * + * @param int|array $media_id Media ID or array of Media IDs. + * @param int $user_id Optional. User ID. Defaults to current logged-in user. + * + * @return bool True if media exists and author matches user ID, false otherwise. + */ +function rtmedia_is_media_owner( $media_id, $user_id = 0 ) { + if ( empty( $media_id ) ) { + return false; + } + + $user_id = ! empty( $user_id ) ? intval( $user_id ) : get_current_user_id(); + if ( empty( $user_id ) ) { + return false; + } + + // Normalize input to a unique array of valid integer IDs. + $media_ids = is_array( $media_id ) ? $media_id : array( $media_id ); + $media_ids = array_filter( array_map( 'intval', $media_ids ) ); + $media_ids = array_unique( $media_ids ); + + if ( empty( $media_ids ) ) { + return false; + } + + $model = new RTMediaModel(); + $media = $model->get( array( 'id' => $media_ids ) ); + + if ( count( $media ) !== count( $media_ids ) ) { + return false; + } + + foreach ( $media as $item ) { + if ( intval( $item->media_author ) !== $user_id ) { + return false; + } + } + + return true; +} + diff --git a/app/main/controllers/upload/RTMediaUploadEndpoint.php b/app/main/controllers/upload/RTMediaUploadEndpoint.php index fa2d1b6fb..5e5f6636a 100755 --- a/app/main/controllers/upload/RTMediaUploadEndpoint.php +++ b/app/main/controllers/upload/RTMediaUploadEndpoint.php @@ -86,11 +86,22 @@ public function template_redirect( $create_activity = true ) { $model = new RTMediaUploadModel(); do_action( 'rtmedia_upload_set_post_object' ); $this->upload = $model->set_post_object(); + unset( $this->upload['activity_id'] ); + + if ( -1 !== $_activity_id && ! empty( $_activity_id ) ) { + $can_attach = false; + // Query the activity to check if the activity belongs to the user. + if ( is_user_logged_in() && function_exists( 'bp_activity_get_specific' ) ) { + $activity = bp_activity_get_specific( array( 'activity_ids' => array( intval( $_activity_id ) ) ) ); + if ( ! empty( $activity['activities'][0] ) && intval( $activity['activities'][0]->user_id ) === get_current_user_id() ) { + $can_attach = true; + } + } - if ( -1 !== $_activity_id ) { - $this->upload['activity_id'] = $_activity_id; - $activity_id = $_activity_id; - + if ( $can_attach ) { + $this->upload['activity_id'] = $_activity_id; + $activity_id = $_activity_id; + } } // Media uploaded into a group takes its privacy from that group. diff --git a/changelog.txt b/changelog.txt index aa271b3c2..753f122a0 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,13 @@ == Changelog == += 4.7.15 [October 13, 2026] = + +* FIXED + * Fixed media ownership verification for activity updates with attached media. + * Fixed media ownership verification for comments on activities and single media. + * Fixed activity ownership verification and input sanitization on media upload endpoint. + + = 4.7.14 [October 06, 2026] = * FIXED diff --git a/index.php b/index.php index 49d8c439e..a1da0a583 100644 --- a/index.php +++ b/index.php @@ -3,7 +3,7 @@ * Plugin Name: rtMedia for WordPress, BuddyPress and bbPress * Plugin URI: https://rtmedia.io/?utm_source=dashboard&utm_medium=plugin&utm_campaign=buddypress-media * Description: This plugin adds missing media rich features like photos, videos and audio uploading to BuddyPress which are essential if you are building social network, seriously! - * Version: 4.7.14 + * Version: 4.7.15 * Requires at least: 4.9.6 * Text Domain: buddypress-media * Author: rtCamp @@ -26,7 +26,7 @@ /** * The version of the plugin */ - define( 'RTMEDIA_VERSION', '4.7.14' ); + define( 'RTMEDIA_VERSION', '4.7.15' ); } if ( ! defined( 'RTMEDIA_PATH' ) ) { diff --git a/languages/buddpress-media.pot b/languages/buddpress-media.pot index f50f35459..2f97e1f3f 100644 --- a/languages/buddpress-media.pot +++ b/languages/buddpress-media.pot @@ -2,14 +2,14 @@ # This file is distributed under the GPLv2 or later. msgid "" msgstr "" -"Project-Id-Version: rtMedia for WordPress, BuddyPress and bbPress 4.7.14\n" +"Project-Id-Version: rtMedia for WordPress, BuddyPress and bbPress 4.7.15\n" "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/buddypress-media\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"POT-Creation-Date: 2026-10-01T07:41:26+00:00\n" +"POT-Creation-Date: 2026-10-13T06:23:39+00:00\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "X-Generator: WP-CLI 2.12.0\n" "X-Domain: buddypress-media\n" @@ -2220,7 +2220,7 @@ msgstr "" #. translators: 1: Username, 2: Number of medias, 3: Media slug. #: app/main/controllers/activity/RTMediaBuddyPressActivity.php:988 #: app/main/controllers/activity/RTMediaBuddyPressActivity.php:991 -#: app/main/controllers/upload/RTMediaUploadEndpoint.php:283 +#: app/main/controllers/upload/RTMediaUploadEndpoint.php:294 #, php-format msgid "%1$s added %2$d %3$s" msgstr "" @@ -3019,18 +3019,18 @@ msgstr "" msgid "Invalid attribute passed for rtmedia_gallery shortcode." msgstr "" -#: app/main/controllers/template/RTMediaTemplate.php:472 -#: app/main/controllers/template/RTMediaTemplate.php:612 -#: app/main/controllers/template/RTMediaTemplate.php:735 -#: app/main/controllers/template/RTMediaTemplate.php:975 +#: app/main/controllers/template/RTMediaTemplate.php:486 +#: app/main/controllers/template/RTMediaTemplate.php:627 +#: app/main/controllers/template/RTMediaTemplate.php:750 +#: app/main/controllers/template/RTMediaTemplate.php:995 msgid "Ooops !!! Invalid access. No nonce was found !!" msgstr "" -#: app/main/controllers/template/RTMediaTemplate.php:482 +#: app/main/controllers/template/RTMediaTemplate.php:496 msgid "Media updated Successfully" msgstr "" -#: app/main/controllers/template/RTMediaTemplate.php:501 +#: app/main/controllers/template/RTMediaTemplate.php:515 msgid "Error in updating Media" msgstr "" diff --git a/languages/buddypress-media.pot b/languages/buddypress-media.pot index f50f35459..2f97e1f3f 100644 --- a/languages/buddypress-media.pot +++ b/languages/buddypress-media.pot @@ -2,14 +2,14 @@ # This file is distributed under the GPLv2 or later. msgid "" msgstr "" -"Project-Id-Version: rtMedia for WordPress, BuddyPress and bbPress 4.7.14\n" +"Project-Id-Version: rtMedia for WordPress, BuddyPress and bbPress 4.7.15\n" "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/buddypress-media\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"POT-Creation-Date: 2026-10-01T07:41:26+00:00\n" +"POT-Creation-Date: 2026-10-13T06:23:39+00:00\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "X-Generator: WP-CLI 2.12.0\n" "X-Domain: buddypress-media\n" @@ -2220,7 +2220,7 @@ msgstr "" #. translators: 1: Username, 2: Number of medias, 3: Media slug. #: app/main/controllers/activity/RTMediaBuddyPressActivity.php:988 #: app/main/controllers/activity/RTMediaBuddyPressActivity.php:991 -#: app/main/controllers/upload/RTMediaUploadEndpoint.php:283 +#: app/main/controllers/upload/RTMediaUploadEndpoint.php:294 #, php-format msgid "%1$s added %2$d %3$s" msgstr "" @@ -3019,18 +3019,18 @@ msgstr "" msgid "Invalid attribute passed for rtmedia_gallery shortcode." msgstr "" -#: app/main/controllers/template/RTMediaTemplate.php:472 -#: app/main/controllers/template/RTMediaTemplate.php:612 -#: app/main/controllers/template/RTMediaTemplate.php:735 -#: app/main/controllers/template/RTMediaTemplate.php:975 +#: app/main/controllers/template/RTMediaTemplate.php:486 +#: app/main/controllers/template/RTMediaTemplate.php:627 +#: app/main/controllers/template/RTMediaTemplate.php:750 +#: app/main/controllers/template/RTMediaTemplate.php:995 msgid "Ooops !!! Invalid access. No nonce was found !!" msgstr "" -#: app/main/controllers/template/RTMediaTemplate.php:482 +#: app/main/controllers/template/RTMediaTemplate.php:496 msgid "Media updated Successfully" msgstr "" -#: app/main/controllers/template/RTMediaTemplate.php:501 +#: app/main/controllers/template/RTMediaTemplate.php:515 msgid "Error in updating Media" msgstr "" diff --git a/readme.txt b/readme.txt index bfa5e285a..431b0d80b 100644 --- a/readme.txt +++ b/readme.txt @@ -5,7 +5,7 @@ License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html Requires at least: 4.9.6 Tested up to: 7.0 -Stable tag: 4.7.14 +Stable tag: 4.7.15 Add albums, photo, audio/video upload, privacy, sharing, front-end uploads & more. All this works on mobile/tablets devices. @@ -128,6 +128,13 @@ http://www.youtube.com/watch?v=dJrykKQGDcs == Changelog == += 4.7.15 [October 13, 2026] = + +* FIXED + * Fixed media ownership verification for activity updates with attached media. + * Fixed media ownership verification for comments on activities and single media. + * Fixed activity ownership verification and input sanitization on media upload endpoint. + = 4.7.14 [October 06, 2026] = * FIXED @@ -1034,6 +1041,9 @@ http://www.youtube.com/watch?v=dJrykKQGDcs == Upgrade Notice == += 4.7.15 = +This release includes important security improvements for media ownership verification and upload endpoint activity authorization. We strongly recommend upgrading. + = 4.7.14 = This release includes important security improvements for media uploads, file extension validation and media edit authorization. We strongly recommend upgrading.