REPORT / 01

Analysis Report · Folder Analysis cache/betterdocs_4.3.3 → cache/betterdocs_4.3.4 — CVE-2025-14980

Shared security patch analysis results

mode patchdiff ai claude_cli haiku
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
Use quotes for exact: "SQL injection" · Operators: hello AND bye, admin OR root, -error, NOT warning
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