From f86e8a49d35f6676b70f85b46d455b205ebe1cb7 Mon Sep 17 00:00:00 2001 From: Intenzi Date: Mon, 12 Oct 2026 13:25:13 +0530 Subject: [PATCH 1/3] fix: enforce media ownership verification for activity and comment attachments --- .../activity/RTMediaBuddyPressActivity.php | 10 +++---- .../controllers/template/RTMediaTemplate.php | 2 +- .../template/rtmedia-ajax-actions.php | 5 +++- .../template/rtmedia-functions.php | 26 +++++++++++++++++++ 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/app/main/controllers/activity/RTMediaBuddyPressActivity.php b/app/main/controllers/activity/RTMediaBuddyPressActivity.php index 1b0aa8693..7bc364365 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[0] ) ) { $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[0] ) && class_exists( 'RTMediaActivity' ) && rtmedia_is_media_owner( $rtmedia_attached_files[0], $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[0], $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/template/RTMediaTemplate.php b/app/main/controllers/template/RTMediaTemplate.php index c058aee2f..c8619810d 100755 --- a/app/main/controllers/template/RTMediaTemplate.php +++ b/app/main/controllers/template/RTMediaTemplate.php @@ -893,7 +893,7 @@ public function check_return_comments() { $comment_content = bp_activity_at_name_filter( $comment_content ); } - if ( ! empty( $rtmedia_attached_files ) ) { + if ( ! empty( $rtmedia_attached_files ) && rtmedia_is_media_owner( $rtmedia_attached_files[0] ) ) { // has media. $comment_with_media = true; diff --git a/app/main/controllers/template/rtmedia-ajax-actions.php b/app/main/controllers/template/rtmedia-ajax-actions.php index 0bc651303..283ee519f 100644 --- a/app/main/controllers/template/rtmedia-ajax-actions.php +++ b/app/main/controllers/template/rtmedia-ajax-actions.php @@ -214,6 +214,9 @@ 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[0] ) ) { + return; + } if ( function_exists( 'rtmedia_get_original_comment_media_content' ) ) { // get the original content of media. @@ -289,7 +292,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[0] ) ) { $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..bd6398904 100644 --- a/app/main/controllers/template/rtmedia-functions.php +++ b/app/main/controllers/template/rtmedia-functions.php @@ -5394,3 +5394,29 @@ function rtmedia_like_eraser( $email_address, $page = 1 ) { 'done' => $done, ); } + +/** + * Check if the given user owns the specified media. + * + * @param int $media_id Media ID. + * @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 ) { + $media_id = intval( $media_id ); + if ( empty( $media_id ) ) { + return false; + } + + $user_id = ! empty( $user_id ) ? intval( $user_id ) : get_current_user_id(); + if ( empty( $user_id ) ) { + return false; + } + + $model = new RTMediaModel(); + $media = $model->get( array( 'id' => $media_id ) ); + + return ! empty( $media ) && intval( $media[0]->media_author ) === $user_id; +} + From 0418b60a8d522dabc09715911e46b53b1b24f346 Mon Sep 17 00:00:00 2001 From: Intenzi Date: Mon, 12 Oct 2026 17:41:42 +0530 Subject: [PATCH 2/3] fix: support batch media ownership validation in rtmedia_is_media_owner --- .../template/rtmedia-functions.php | 28 +++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/app/main/controllers/template/rtmedia-functions.php b/app/main/controllers/template/rtmedia-functions.php index bd6398904..623761ed3 100644 --- a/app/main/controllers/template/rtmedia-functions.php +++ b/app/main/controllers/template/rtmedia-functions.php @@ -5398,13 +5398,12 @@ function rtmedia_like_eraser( $email_address, $page = 1 ) { /** * Check if the given user owns the specified media. * - * @param int $media_id Media ID. - * @param int $user_id Optional. User ID. Defaults to current logged-in user. + * @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 ) { - $media_id = intval( $media_id ); if ( empty( $media_id ) ) { return false; } @@ -5414,9 +5413,28 @@ function rtmedia_is_media_owner( $media_id, $user_id = 0 ) { 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_id ) ); + $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 ! empty( $media ) && intval( $media[0]->media_author ) === $user_id; + return true; } From 6fd5cb709983a7c7399a1e24be944cfc73e40799 Mon Sep 17 00:00:00 2001 From: Intenzi Date: Mon, 12 Oct 2026 17:44:28 +0530 Subject: [PATCH 3/3] fix: validate all attached media and prevent metadata mutation --- .../activity/RTMediaBuddyPressActivity.php | 6 ++-- app/main/controllers/media/RTMediaComment.php | 2 +- .../controllers/template/RTMediaTemplate.php | 19 ++++++---- .../template/rtmedia-ajax-actions.php | 36 +++++++++---------- 4 files changed, 33 insertions(+), 30 deletions(-) diff --git a/app/main/controllers/activity/RTMediaBuddyPressActivity.php b/app/main/controllers/activity/RTMediaBuddyPressActivity.php index 7bc364365..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 ) && rtmedia_is_media_owner( $rtmedia_attached_files[0] ) ) { + 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' ) && rtmedia_is_media_owner( $rtmedia_attached_files[0], $user_id ) ) { + 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' ); @@ -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 ) && rtmedia_is_media_owner( $rtmedia_attached_files[0], $user_id ) ) { + 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 c8619810d..37f447c14 100755 --- a/app/main/controllers/template/RTMediaTemplate.php +++ b/app/main/controllers/template/RTMediaTemplate.php @@ -893,13 +893,18 @@ public function check_return_comments() { $comment_content = bp_activity_at_name_filter( $comment_content ); } - if ( ! empty( $rtmedia_attached_files ) && rtmedia_is_media_owner( $rtmedia_attached_files[0] ) ) { - // 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 ( ! empty( $rtmedia_attached_files ) ) { + 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 283ee519f..6034e39b9 100644 --- a/app/main/controllers/template/rtmedia-ajax-actions.php +++ b/app/main/controllers/template/rtmedia-ajax-actions.php @@ -214,27 +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[0] ) ) { - return; - } + 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 ); @@ -292,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' ) && rtmedia_is_media_owner( $rtmedia_attached_files[0] ) ) { + 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(); }