REPORT / 01
Analysis Report · Folder Analysis cache/betterdocs_4.3.3 → cache/betterdocs_4.3.4 — CVE-2025-14980
Shared security patch analysis results
02 ·
Lifecycle actions
cancel · resume · skip · regenerate
03 ·
Share this analysis
copy link · embed report
03 ·
CVE Security Analysis & Writeups
ai-generated · per cve
Comprehensive security analysis generated by AI for each confirmed CVE match. Click on a CVE to view the detailed writeup including vulnerability background, technical details, patch analysis, and PoC guide.
CVE-2025-14980
NVD
AI-Generated Analysis
05 ·
Findings
filter · search · paginate
Showing 0 to 0 of 0 results
includes/Core/Admin.php
AI: 1 vulnerabilities
1 true positive
CVE-2025-14980
--- cache/betterdocs_4.3.3/includes/Core/Admin.php 2026-01-10 00:35:00.982694010 +0000+++ cache/betterdocs_4.3.4/includes/Core/Admin.php 2026-01-10 00:35:45.777446892 +0000@@ -688,32 +688,31 @@ 'doc_cat_order_nonce' => wp_create_nonce( 'doc_cat_order_nonce' ), 'knowledge_base_order_nonce' => wp_create_nonce( 'knowledge_base_order_nonce' ), 'paged' => isset( $_GET['paged'] ) ? absint( wp_unslash( $_GET['paged'] ) ) : 0, // phpcs:ignore WordPress.Security.NonceVerification.Missing- 'per_page_id' => 'edit_doc_category_per_page',- 'menu_title' => __( 'Switch to BetterDocs UI', 'betterdocs' ),- 'dark_mode' => $dark_mode,- 'text' => __( 'Copied!', 'betterdocs' ),- 'test_report' => __( 'Test Report!', 'betterdocs' ),- 'sending' => __( 'Sending...', 'betterdocs' ),- 'dir_url' => BETTERDOCS_ABSURL,- 'rest_url' => esc_url_raw( rest_url() ),- 'free_version' => betterdocs()->version,- 'generate_data_url' => get_rest_url( null, '/betterdocs/v1/create-sample-docs' ),- 'nonce' => wp_create_nonce( 'wp_rest' ),- 'sync_nonce' => wp_create_nonce( 'ai_chatbot_embed' ),- 'count_all_docs' => array_sum((array) wp_count_posts('docs')),- 'count_all_faq' => array_sum((array) wp_count_posts('betterdocs_faq')),- 'count_new_docs' => count(get_option('saved_docs_post_ids', [])) + count(get_option('betterdocs_ai_chatbot_error_posts', [])),- 'admin_url' => admin_url(),- 'ia_preview' => betterdocs()->settings->get( 'ia_enable_preview', false ),- 'multiple_kb' => betterdocs()->settings->get( 'multiple_kb' ),- 'previewMode' => betterdocs()->settings->get( 'ia_enable_preview', false ),- 'dashboard_mode' => get_option( 'dashboard_mode' ),- 'betterdocs_pro_plugin' => betterdocs()->is_pro_active(),- 'betterdocs_pro_version' => betterdocs()->pro_version(),- 'analytics_older' => version_compare( betterdocs()->pro_version(), '3.3.4', '<=' ),- 'disabled_embed_model_option' => get_option('disabled_embed_model_option'),- 'betterdocs_ChatBot_plugin' => is_plugin_active( 'betterdocs-ai-chatbot/betterdocs-ai-chatbot.php' ),- 'total_doc_category_terms' => wp_count_terms( 'doc_category')+ 'per_page_id' => 'edit_doc_category_per_page',+ 'menu_title' => __( 'Switch to BetterDocs UI', 'betterdocs' ),+ 'dark_mode' => $dark_mode,+ 'text' => __( 'Copied!', 'betterdocs' ),+ 'test_report' => __( 'Test Report!', 'betterdocs' ),+ 'sending' => __( 'Sending...', 'betterdocs' ),+ 'dir_url' => BETTERDOCS_ABSURL,+ 'rest_url' => esc_url_raw( rest_url() ),+ 'free_version' => betterdocs()->version,+ 'generate_data_url' => get_rest_url( null, '/betterdocs/v1/create-sample-docs' ),+ 'nonce' => wp_create_nonce( 'wp_rest' ),+ 'sync_nonce' => wp_create_nonce( 'ai_chatbot_embed' ),+ 'count_all_docs' => array_sum((array) wp_count_posts('docs')),+ 'count_all_faq' => array_sum((array) wp_count_posts('betterdocs_faq')),+ 'count_new_docs' => count(get_option('saved_docs_post_ids', [])) + count(get_option('betterdocs_ai_chatbot_error_posts', [])),+ 'admin_url' => admin_url(),+ 'ia_preview' => betterdocs()->settings->get( 'ia_enable_preview', false ),+ 'multiple_kb' => betterdocs()->settings->get( 'multiple_kb' ),+ 'previewMode' => betterdocs()->settings->get( 'ia_enable_preview', false ),+ 'dashboard_mode' => get_option( 'dashboard_mode' ),+ 'betterdocs_pro_plugin' => betterdocs()->is_pro_active(),+ 'betterdocs_pro_version' => betterdocs()->pro_version(),+ 'analytics_older' => version_compare( betterdocs()->pro_version(), '3.3.4', '<=' ),+ 'disabled_embed_model_option' => get_option('disabled_embed_model_option'),+ 'betterdocs_ChatBot_plugin' => is_plugin_active( 'betterdocs-ai-chatbot/betterdocs-ai-chatbot.php' ) ] ); @@ -735,34 +734,42 @@ remove_action( 'wp_head', 'print_emoji_detection_script', 7 ); remove_action( 'admin_print_scripts', 'print_emoji_detection_script' ); - betterdocs()->assets->localize(- 'betterdocs-admin-faq',- 'betterdocsFaq',- [- 'dir_url' => BETTERDOCS_ABSURL,- 'rest_url' => esc_url_raw( rest_url() ),- 'free_version' => betterdocs()->version,- 'nonce' => wp_create_nonce( 'wp_rest' ),- 'betterdocs_settings' => get_option( 'betterdocs_settings', false )- ]- );-- //Glossaries Related Localization- betterdocs()->assets->enqueue( 'betterdocs-admin-glossaries', 'admin/css/faq.css' ); - betterdocs()->assets->enqueue( 'betterdocs-admin-glossaries', 'admin/js/glossaries.js' );+ // Get settings and remove unnecessary keys+ $betterdocs_settings = get_option( 'betterdocs_settings', false );+ if ( is_array( $betterdocs_settings ) && ! current_user_can( 'edit_docs_settings' ) ) {+ unset( $betterdocs_settings['ai_autowrite_api_key'] );+ unset( $betterdocs_settings['ai_chatbot_api_key'] );+ } - betterdocs()->assets->localize(- 'betterdocs-admin-glossaries',- 'betterdocsGlossary',- [- 'dir_url' => BETTERDOCS_ABSURL,- 'rest_url' => esc_url_raw( rest_url() ),- 'free_version' => betterdocs()->version,- 'nonce' => wp_create_nonce( 'wp_rest' ),- 'betterdocs_settings' => get_option( 'betterdocs_settings', false )- ]- );+ betterdocs()->assets->localize(+ 'betterdocs-admin-faq',+ 'betterdocsFaq',+ [+ 'dir_url' => BETTERDOCS_ABSURL,+ 'rest_url' => esc_url_raw( rest_url() ),+ 'free_version' => betterdocs()->version,+ 'nonce' => wp_create_nonce( 'wp_rest' ),+ 'betterdocs_settings' => $betterdocs_settings+ ]+ );++ //Glossaries Related Localization+ betterdocs()->assets->enqueue( 'betterdocs-admin-glossaries', 'admin/css/faq.css' );++ betterdocs()->assets->enqueue( 'betterdocs-admin-glossaries', 'admin/js/glossaries.js' );++ betterdocs()->assets->localize(+ 'betterdocs-admin-glossaries',+ 'betterdocsGlossary',+ [+ 'dir_url' => BETTERDOCS_ABSURL,+ 'rest_url' => esc_url_raw( rest_url() ),+ 'free_version' => betterdocs()->version,+ 'nonce' => wp_create_nonce( 'wp_rest' ),+ 'betterdocs_settings' => $betterdocs_settings+ ]+ ); } /**
AI Analysis
```
Vulnerability Existed: yes
TRUE POSITIVE
Sensitive Data Exposure - CWE-200 - includes/Core/Admin.php - Lines 747-755
Old Code:
'betterdocs_settings' => get_option( 'betterdocs_settings', false )
Fixed Code:
$betterdocs_settings = get_option( 'betterdocs_settings', false );
if ( is_array( $betterdocs_settings ) && ! current_user_can( 'edit_docs_settings' ) ) {
unset( $betterdocs_settings['ai_autowrite_api_key'] );
unset( $betterdocs_settings['ai_chatbot_api_key'] );
}
'betterdocs_settings' => $betterdocs_settings
Explanation:
The old code was exposing sensitive API keys ('ai_autowrite_api_key' and 'ai_chatbot_api_key') from the betterdocs_settings option to the frontend JavaScript context via localization, without checking user capabilities. This exposed sensitive credentials to users who may not have permission to view them. The fix filters out these sensitive keys before localization when the user lacks the 'edit_docs_settings' capability, preventing unauthorized access to API credentials in the frontend scope.
```
CVE Analysis Results:
CVE-2025-14980: Yes
View CVE Description
The BetterDocs plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 4.3.3 via the scripts() function. This makes it possible for authenticated attackers, with contributor-level access and above, to extract sensitive data including the OpenAI API key stored in plugin settings.
includes/Core/Settings.php
AI: 1 vulnerabilities
1 true positive
CVE-2025-14980
--- cache/betterdocs_4.3.3/includes/Core/Settings.php 2026-01-10 00:35:00.982694010 +0000+++ cache/betterdocs_4.3.4/includes/Core/Settings.php 2026-01-10 00:35:45.781447138 +0000@@ -85,11 +85,21 @@ wp_enqueue_media(); wp_enqueue_script( 'betterdocs-admin' );- betterdocs()->assets->localize( 'betterdocs-admin', 'betterdocsAdminSettings', GlobalFields::normalize( $this->settings_args() ) );+ + $settings = GlobalFields::normalize( $this->settings_args() );+ + // Remove sensitive API keys if user doesn't have permission to edit settings+ if ( ! current_user_can( 'edit_docs_settings' ) ) {+ if ( isset( $settings['values']['ai_autowrite_api_key'] ) ) {+ unset( $settings['values']['ai_autowrite_api_key'] );+ }+ if ( isset( $settings['values']['ai_chatbot_api_key'] ) ) {+ unset( $settings['values']['ai_chatbot_api_key'] );+ }+ }+ + betterdocs()->assets->localize( 'betterdocs-admin', 'betterdocsAdminSettings', $settings ); betterdocs()->assets->enqueue( 'betterdocs-icons', 'admin/btd-icon/style.css' );-- // betterdocs()->assets->enqueue( 'betterdocs-settings', 'admin/css/settings.css' );- // betterdocs()->assets->enqueue( 'betterdocs-settings', 'admin/js/settings.js' ); } public function enqueue_old( $hook ) {@@ -2272,45 +2282,6 @@ ] ] ] ),- // 'tab-ai-chatbot' => [- // 'id' => 'tab-ai-chatbot',- // 'name' => 'tab-ai-chatbot',- // 'type' => 'section',- // 'label' => __( 'AI Chatbot', 'betterdocs' ),- // // 'is_pro' => ! defined('BETTERDOCS_PRO_VERSION'),- // 'priority' => 76,- // 'save' => false,- // 'submit' => [- // 'show' => false- // ],-- // 'fields' => [- // 'title-ai-chatbot' => apply_filters( 'betterdocs_settings_ai_chatbot_fields', [- // 'name' => 'title-ai-chatbot-tab',- // 'type' => 'section',- // 'label' => __( 'AI Chatbot', 'betterdocs' ),- // 'priority' => 60,- // 'save' => false,- // 'submit' => [- // 'show' => false- // ],-- // 'fields' => [- // 'enable_ai_chatbot' => [- // 'name' => 'enable_ai_chatbot',- // 'label' => __( 'AI Chatbot', 'betterdocs' ),- // 'description' => __( 'Enable AI Chatbot', 'betterdocs' ),- // 'type' => 'toggle',- // 'priority' => 5,- // 'default' => 0,- // 'is_pro' => true,- // 'is_license_active' => false,- // 'disabled' => ! betterdocs()->is_pro_active() || ! defined( 'BETTERDOCS_CHATBOT_FILE' )- // ],- // ]- // ] ),- // ]- // ], ] ), 'TAB_AI_CHATBOT' => get_option( 'enable_ai_chatbot' ), 'CHATBOT_LICENSE' => get_option( 'betterdocs_chatbot_software__license_status' ),
AI Analysis
Vulnerability Existed: yes
TRUE POSITIVE
Insufficient Access Control - CWE-639 - includes/Core/Settings.php lines 88-101
Old Code:
```php
betterdocs()->assets->localize( 'betterdocs-admin', 'betterdocsAdminSettings', GlobalFields::normalize( $this->settings_args() ) );
```
Fixed Code:
```php
$settings = GlobalFields::normalize( $this->settings_args() );
// Remove sensitive API keys if user doesn't have permission to edit settings
if ( ! current_user_can( 'edit_docs_settings' ) ) {
if ( isset( $settings['values']['ai_autowrite_api_key'] ) ) {
unset( $settings['values']['ai_autowrite_api_key'] );
}
if ( isset( $settings['values']['ai_chatbot_api_key'] ) ) {
unset( $settings['values']['ai_chatbot_api_key'] );
}
}
betterdocs()->assets->localize( 'betterdocs-admin', 'betterdocsAdminSettings', $settings );
```
Explanation:
The original code passed all settings (including sensitive API keys: `ai_autowrite_api_key` and `ai_chatbot_api_key`) to the frontend via `wp_localize_script()` without any permission checks. This exposed sensitive credentials to all users viewing the admin interface, regardless of their role or capabilities. The fix adds a capability check (`current_user_can( 'edit_docs_settings' )`) and conditionally removes API keys from the frontend-exposed settings for users who lack the required permission. This properly restricts sensitive data to authorized users only, mitigating information disclosure and privilege escalation risks.
CVE Analysis Results:
CVE-2025-14980: Yes
View CVE Description
The BetterDocs plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 4.3.3 via the scripts() function. This makes it possible for authenticated attackers, with contributor-level access and above, to extract sensitive data including the OpenAI API key stored in plugin settings.
Showing 1 to 2 of 2 results