GiveWP <= 4.14.5 - Missing Authorization
Description
The GiveWP plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 4.14.5. This makes it possible for unauthenticated attackers to perform an unauthorized action.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:NTechnical Details
What Changed in the Fix
Changes introduced in v4.14.6
Source Code
WordPress.org SVN# GiveWP <= 4.14.5 - Missing Authorization Research Plan ## 1. Vulnerability Summary The GiveWP plugin (up to version 4.14.5) is vulnerable to **Missing Authorization** in its REST API implementation, specifically within the new Campaigns (V3) functionality. The `CampaignCommentsController` and pot…
Show full research plan
GiveWP <= 4.14.5 - Missing Authorization Research Plan
1. Vulnerability Summary
The GiveWP plugin (up to version 4.14.5) is vulnerable to Missing Authorization in its REST API implementation, specifically within the new Campaigns (V3) functionality. The CampaignCommentsController and potentially routes within CampaignController allow unauthenticated access to campaign-related data or actions due to improper use of permission_callback or missing capability checks within the callback. While some routes use UserPermissions facades, the CampaignCommentsController explicitly uses __return_true, potentially allowing unauthenticated users to query donation comments from any campaign, regardless of status (Draft, Private).
2. Attack Vector Analysis
- Endpoint:
/wp-json/give-api/v3/campaign/{id}/comments - Method:
GET(as defined inCampaignCommentsController.php) - Vulnerable Parameter:
id(Campaign ID) - Authentication: None required (
PR:N) - Preconditions: At least one campaign must exist (even in Draft or Private status) with donation comments.
3. Code Flow
- Entry Point: The REST API route is registered in
Give\API\REST\V3\Routes\Campaigns\CampaignCommentsController::register_routes(). - Authorization Check: The
permission_callbackis set to__return_true, which bypass
Summary
The GiveWP plugin for WordPress is vulnerable to unauthorized access in versions up to 4.14.5. The REST API endpoint for campaign comments fails to perform a capability check or validate campaign visibility, allowing unauthenticated attackers to view donation comments from any campaign, including those in draft or private status.
Vulnerable Code
// src/API/REST/V3/Routes/Campaigns/CampaignCommentsController.php line 42 'permission_callback' => '__return_true', --- // src/API/REST/V3/Routes/Campaigns/CampaignCommentsController.php line 78 public function get_items($request): WP_REST_Response { $campaignId = $request->get_param('id'); $perPage = $request->get_param('perPage'); $anonymous = $request->get_param('anonymous'); $campaign = Campaign::find($campaignId); if (!$campaign) { $response = new WP_Error('campaign_not_found', __('Campaign not found', 'give'), ['status' => 404]); return rest_ensure_response($response); } $query = (new CampaignDonationQuery($campaign))
Security Fix
@@ -38,7 +39,7 @@ [ 'methods' => WP_REST_Server::READABLE, 'callback' => [$this, 'get_items'], - 'permission_callback' => '__return_true', + 'permission_callback' => '__return_true', // Public endpoint; access is validated inside get_items() based on campaign status and page privacy. 'args' => [ 'id' => [ 'type' => 'integer', @@ -79,6 +83,11 @@ if (!$campaign) { $response = new WP_Error('campaign_not_found', __('Campaign not found', 'give'), ['status' => 404]); + + return rest_ensure_response($response); + } + + if (!CampaignPermissions::canView($campaign)) { + $response = new WP_Error('rest_forbidden', __('You do not have permission to view this campaign.', 'give'), ['status' => 403]); return rest_ensure_response($response); }
Exploit Outline
The vulnerability can be exploited by an unauthenticated attacker by targeting the REST API endpoint for campaign comments. 1. Target Endpoint: `/wp-json/give-api/v3/campaign/{id}/comments` where `{id}` is the ID of a campaign. 2. Payload: A simple GET request to the endpoint. No special payload shape or parameters are required beyond the campaign ID. 3. Methodology: - The attacker identifies a campaign ID (potentially through enumeration or by finding IDs of private/draft campaigns). - The attacker sends a GET request to the vulnerable endpoint without any authentication headers. - Because the `permission_callback` is hardcoded to `__return_true` and the handler originally lacked checks for the campaign's status (e.g., Draft, Private) or the current user's permissions, the plugin returns the donation comments associated with that campaign, disclosing sensitive donor information.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.