weDocs: AI Powered Knowledge Base, Docs, Documentation, Wiki & AI Chatbot <= 2.1.15 - Unauthenticated Sensitive Information Exposure
Description
The weDocs plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 2.1.15 via the `/wp-json/wp/v2/docs/settings` REST API endpoint. This makes it possible for unauthenticated attackers to extract sensitive data including third party services API keys.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:NTechnical Details
What Changed in the Fix
Changes introduced in v2.1.16
Source Code
WordPress.org SVN# Exploitation Research Plan: CVE-2025-14574 (weDocs Sensitive Information Exposure) ## 1. Vulnerability Summary The **weDocs** plugin for WordPress (versions up to and including 2.1.15) contains an unauthenticated sensitive information exposure vulnerability. The plugin registers a REST API endpoi…
Show full research plan
Exploitation Research Plan: CVE-2025-14574 (weDocs Sensitive Information Exposure)
1. Vulnerability Summary
The weDocs plugin for WordPress (versions up to and including 2.1.15) contains an unauthenticated sensitive information exposure vulnerability. The plugin registers a REST API endpoint /wp-json/wp/v2/docs/settings that allows unauthenticated access to the plugin's internal settings. These settings can include sensitive third-party API keys (e.g., OpenAI, Anthropic, or Cloudflare Turnstile) used for the plugin's AI features.
The flaw exists in includes/API/SettingsApi.php within the register_api method, where the READABLE route for the settings base is defined with a permission_callback set to __return_true.
2. Attack Vector Analysis
- Endpoint:
GET /wp-json/wp/v2/docs/settings - Vulnerable Parameter:
data(Query String) - Required Value:
wedocs_settings - Authentication: None (Unauthenticated)
- Preconditions: The site must have settings saved in the
wedocs_settingsoption (common if AI features or specific configurations are enabled).
3. Code Flow
- Route Registration: In
includes/API/SettingsApi.php, theregister_api()method (lines 66-104) defines the route:- Namespace/Version:
wp/v2 - Base:
docs/settings methods:WP_REST_Server::READABLE(GET)permission_callback:__return_true(Line 73)
- Namespace/Version:
- Callback Execution: When a GET request is made to this route,
get_items($request)is called (line 134). - Parameter Processing: The function retrieves the
dataparameter:$get_data = $request->get_param( 'data' );(line 136). - Information Leak: If
$get_dataequals'wedocs_settings', the code executes$value = get_option( 'wedocs_settings', array() );and returns the entire array viarest_ensure_response( $value ). - Data Content: The
wedocs_settingsoption contains nested arrays, including anaikey which stores provider configurations andapi_keyvalues (as seen in thesanitize_ai_settingslogic on line 186).
4. Nonce Acquisition Strategy
No nonce is required.
The REST API route is specifically registered with 'permission_callback' => '__return_true', which bypasses the default WordPress REST API nonce check for non-public routes. Standard WordPress REST API GET requests for public resources do not require the _wpnonce parameter or X-WP-Nonce header.
5. Exploitation Strategy
The goal is to retrieve the wedocs_settings option and confirm the presence of sensitive API keys.
Step-by-Step Plan:
- Trigger Request: Use the
http_requesttool to perform a GET request to the vulnerable endpoint. - Target URL:
{{BASE_URL}}/wp-json/wp/v2/docs/settings?data=wedocs_settings - Payload Construction: No body is required.
- Header:
Accept: application/json - Analysis: Inspect the JSON response for the presence of the
aiobject and itsproviderslist.
6. Test Data Setup
To demonstrate the impact, we must first populate the settings with a "sensitive" key.
- Requirement: The plugin must be installed and active.
- Populate Settings: Use WP-CLI to simulate an admin configuring an OpenAI API key:
wp option update wedocs_settings '{"ai":{"default_provider":"openai","providers":{"openai":{"api_key":"sk-test-vulnerable-key-12345","model":"gpt-4"}}}}' --format=json
7. Expected Results
A successful exploit will return a 200 OK response with a JSON body similar to:
{
"ai": {
"default_provider": "openai",
"providers": {
"openai": {
"api_key": "sk-test-vulnerable-key-12345",
"model": "gpt-4"
}
}
}
}
8. Verification Steps
- Verify via API: Run the exploit request using
http_request. - Cross-Verify via CLI: Confirm the data returned matches the database state:
wp option get wedocs_settings --format=json - Compare Results: Ensure the
api_keyfield in the API response matches the value set in the setup step.
9. Alternative Approaches
Target Turnstile Site Key
The plugin also exposes a specific endpoint for the Cloudflare Turnstile site key:
- Endpoint:
GET /wp-json/wp/v2/docs/settings/turnstile-site-key - Code Reference:
includes/API/SettingsApi.phpline 98. - Permission: Also uses
__return_true. - Payload: No parameters required.
- Significance: While the site key is usually public, exposing it through an API endpoint allows for automated scraping of site infrastructure details.
Target Specific "Data" Keys
The get_items function currently only checks for wedocs_settings. However, researchers should check if subsequent versions or hooks (like wedocs_settings_data) allow for other sensitive keys to be leaked through the same logic.
Summary
The weDocs plugin for WordPress (versions up to 2.1.15) contains an unauthenticated sensitive information exposure vulnerability via its REST API. The endpoint /wp-json/wp/v2/docs/settings incorrectly uses __return_true as a permission callback, allowing any visitor to retrieve the plugin's full configuration, including secret API keys for AI services like OpenAI and Anthropic.
Vulnerable Code
// includes/API/SettingsApi.php:66 public function register_api() { register_rest_route( $this->namespace . $this->version, '/' . $this->base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => '__return_true', ), --- // includes/API/SettingsApi.php:134 public function get_items( $request ) { $value = array(); $get_data = $request->get_param( 'data' ); if ( 'wedocs_settings' === $get_data ) { $value = get_option( 'wedocs_settings', array() ); } return rest_ensure_response( $value ); } --- // includes/API/SettingsApi.php:98 register_rest_route( $this->namespace . $this->version, '/' . $this->base . '/turnstile-site-key', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_turnstile_site_key' ), 'permission_callback' => '__return_true', ), ) );
Security Fix
@@ -70,7 +70,11 @@ array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), - 'permission_callback' => '__return_true', + 'permission_callback' => function () { + return current_user_can( 'manage_options' ); + }, ), array( 'methods' => WP_REST_Server::CREATABLE, @@ -101,7 +101,9 @@ register_rest_route( $this->namespace . $this->version, '/' . $this->base . '/turnstile-site-key', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_turnstile_site_key' ), - 'permission_callback' => '__return_true', + 'permission_callback' => function () { + return current_user_can( 'manage_options' ); + }, ), ) );
Exploit Outline
The exploit targets the weDocs REST API settings endpoint which lacks proper authorization checks. An unauthenticated attacker can retrieve sensitive information by following these steps: 1. Identify a WordPress site running weDocs version 2.1.15 or earlier. 2. Send a GET request to the endpoint: `/wp-json/wp/v2/docs/settings?data=wedocs_settings`. 3. No authentication headers or nonces are required because the 'permission_callback' is hardcoded to return true. 4. The server will respond with a 200 OK and a JSON body containing the 'wedocs_settings' database option. 5. The attacker can then parse the 'ai' key within the response to find cleartext API keys for providers like OpenAI, Anthropic, or Cloudflare.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.