The plugin was affected by Missing Authorization and Cross-Site Request Forgery (CSRF) vulnerabilities.

The plugin creates a frontend user profile, groups, communities and messenger. However, the messenger is vulnerable because there is no user authentication, so the vulnerability allows us to list and modify other users’ messages.


Let’s check the plugin

To use this plugin, we need to log in with a user (even with the lowest privileges), but since this plugin is a social, community and profile plugin, we can assume that there will be an option to register on the website.

We can add the messenger using the [profilegrid_messaging_area] shortcode. Then we get an ajax-based messenger, where we can write messages to other users, which will be a thread. We also have the option to edit messages.

The pm_messenger_show_messages ajax action is handled by the following ProfileMagic_Chat class method:

public function pm_messenger_show_messages( $tid, $loadnum, $timezone = 0, $search = '' ){}

which calls the following function:

$pmrequests->get_message_of_thread( $tid, $limit, $offset, $descending, $search );

which executes the following query:

$message = $dbhandler->get_all_result( $identifier, $column = '*', array( 't_id' => $tid ), 'results', $offset, $limit, $sort_by = 'timestamp', $descending, $additional );

We can clearly see that there is no user identification or authentication anywhere in the code, so nowhere does the plugin check which user is querying whose messages. This gives us the opportunity to query the messages of other users only by knowing the thread id.

Another vulnerability is that there is no nonce check, so we can even send a request using Postman.

Another is the pm_messenger_send_new_message ajax action, which allows us to write a new message or edit an existing message. The following method handles it in Profile_Magic_Public class:

public function pm_messenger_send_new_message() {}

Which can call these two functions to add or edit a message:

if ( $mid == '' ) {
	$result = $pmmessenger->pm_messenger_send_new_message( $rid, $content );
} else {
	$result = $pmmessenger->pm_messenger_send_edit_message( $rid, $mid, $content );

Let’s check the editing, because it’s more interesting:

The pm_edit_message method in the PM_request class uses the following function to edit the message:

$mid = $dbhandler->update_row( $identifier, 'm_id', $mid, $data );

We can clearly see that the message is edited only based on the message id (which is $mid).


Let’s see how we can exploit this vulnerability

First, we need to log in to the website. Our username on the test website is spy. And there is a user1 and a user2 in test website.

We only need to send a POST request to exploit this vulnerability.

The HTTP request to the which is a test WordPress website:

POST /vdb/metagauss-profilegrid/wp-admin/admin-ajax.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded


Since there is no nonce validation, this request can be sent from anywhere.

And we get the list of messages:

message1 from user1 to user2
11 Aug,5:21 AM

message2 from user1 to user2
11 Aug,5:21 AM

message3 from user1 to user2
11 Aug,5:21 AM

reply1 from user2 to user1
11 Aug,5:23 AM


Let’s check how we can exploit the message editing vulnerability:

For this we will need the nonce field, but this can be found in the html. After that, we need to send a POST request to exploit this vulnerability.

The HTTP request:

POST /vdb/metagauss-profilegrid/wp-admin/admin-ajax.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded


We use these values:

tid (thread id): 1
rid (receiver user id): - (which can be anything, just don’t be empty)
mid (message id): 1 (which we can find in the html when querying the messages)
content (message content): message1 from user1 to user2 (edited by spy)

After sending the request, the content of the message is changed. However, this message was sent by user1 to user2, so we should not be able to modify it.


Try it

Feel free to try and use the WordPress websites for testing. I have set the roles and capabilities, so you can only get low level access to the website.




Additional tests

I created a Postman request for exploit: Postman Web – ProfileGrid by Metagauss WordPress plugin Missing Authorization Collection

Can be used by anyone after fork. The required variables are stored in the collection.