CVE-2026-15104

BetterDocs <= 4.6.0 - Authenticated (Custom+) SQL Injection via 'lang' Parameter

mediumImproper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
6.5
CVSS Score
6.5
CVSS Score
medium
Severity
4.6.1
Patched in
1d
Time to patch

Description

The BetterDocs – AI Documentation, Knowledge Base, Docs, Wikis, FAQ with Chatbot plugin for WordPress is vulnerable to generic SQL Injection via the 'lang' parameter in all versions up to, and including, 4.6.0 due to insufficient escaping on the user supplied parameter and lack of sufficient preparation on the existing SQL query. This makes it possible for authenticated attackers, with custom-level access and above, to append additional SQL queries into already existing queries that can be used to extract sensitive information from the database. Exploitation requires a supported multilingual plugin (WPML, Polylang, qTranslate, Weglot, or TranslatePress) to be active on the site, as the vulnerable code path is gated by Helper::is_multilingual_active().

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
High
Confidentiality
None
Integrity
None
Availability

Technical Details

Affected versions<=4.6.0
PublishedJuly 9, 2026
Last updatedJuly 10, 2026
Affected pluginbetterdocs

What Changed in the Fix

Changes introduced in v4.6.1

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

I cannot fulfill this request. I am prohibited from generating actionable exploitation material, including research plans, step-by-step guides, or specific payloads designed to exploit vulnerabilities in software. My safety guidelines prioritize preventing real-world harm, which includes declining r…

Show full research plan

I cannot fulfill this request. I am prohibited from generating actionable exploitation material, including research plans, step-by-step guides, or specific payloads designed to exploit vulnerabilities in software. My safety guidelines prioritize preventing real-world harm, which includes declining requests that act as a force multiplier for cyberattacks.

For information on how to identify and remediate similar security issues, I recommend searching for resources on WordPress Plugin Security Best Practices, specifically regarding:

  • The proper use of the $wpdb->prepare() method for parameterizing database queries.
  • The WordPress REST API security model and the use of permission_callback.
  • Input validation and sanitization techniques using functions like sanitize_text_field() and absint().
  • The OWASP Top 10 guidance on SQL Injection prevention.

Resources such as the WordPress Plugin Handbook provide extensive documentation for developers on building secure extensions and protecting against common attack vectors.

Research Findings
Static analysis — not yet PoC-verified

Summary

BetterDocs (<= 4.6.0) is vulnerable to SQL Injection through the 'lang' parameter in REST API requests for document categories and tags. This occurs because the plugin lacks proper escaping and SQL preparation when processing the language filter, particularly when a multilingual plugin like WPML or Polylang is active, allowing authenticated users with docs-level permissions to extract database information.

Vulnerable Code

// includes/Core/PostType.php (Line 102)
add_filter( 'rest_doc_category_query', [ $this, 'modify_doc_category_rest_query' ], 10, 2 );

---

// includes/Core/PostType.php (Line 144)
add_filter( 'rest_doc_tag_query', [ $this, 'modify_doc_tag_rest_query' ], 10, 2 );

---

// includes/Core/PostType.php (Lines 117-142)
// Expose (and allow setting) a term's language for WPML/Polylang so the React
// admin can show a language filter bar + a language selector. Applies to both
// the doc_category and doc_tag taxonomies.
foreach ( [ $this->category, $this->tag ] as $bd_lang_taxonomy ) {
	register_rest_field(
		$bd_lang_taxonomy,
		'lang',
		[
			'get_callback'    => function ( $item ) use ( $bd_lang_taxonomy ) {
				if ( ! Helper::is_multilingual_active() ) {
					return null;
				}
				$term = get_term( $item['id'], $bd_lang_taxonomy );
				return ( $term && ! is_wp_error( $term ) ) ? Helper::get_term_language( $term ) : '';
			},
			'update_callback' => function ( $value, $term ) {
				if ( ! current_user_can( 'edit_docs' ) || ! Helper::is_multilingual_active() ) {
					return;
				}
				Helper::set_term_language( $term, sanitize_text_field( (string) $value ) );
			},
			'schema'          => [
				'type'    => [ 'string', 'null' ],
				'context' => [ 'view', 'edit' ],
			],
		]
	);
}

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/betterdocs/4.6.0/assets/admin/js/dashboard.asset.php /home/deploy/wp-safety.org/data/plugin-versions/betterdocs/4.6.1/assets/admin/js/dashboard.asset.php
--- /home/deploy/wp-safety.org/data/plugin-versions/betterdocs/4.6.0/assets/admin/js/dashboard.asset.php	2026-07-07 09:55:00.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/betterdocs/4.6.1/assets/admin/js/dashboard.asset.php	2026-07-09 11:26:26.000000000 +0000
@@ -1 +1 @@
-<?php return array('dependencies' => array('lodash', 'moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-components', 'wp-compose', 'wp-data', 'wp-date', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-media-utils', 'wp-url'), 'version' => 'ebf8115eb196d6faa129');
+<?php return array('dependencies' => array('lodash', 'moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-components', 'wp-compose', 'wp-data', 'wp-date', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-media-utils', 'wp-url'), 'version' => '0b931dd7721a0b1f161f');

Exploit Outline

The vulnerability is exploited by targeting the WordPress REST API endpoints for BetterDocs taxonomies, such as `/wp-json/wp/v2/doc_category` or `/wp-json/wp/v2/doc_tag`. An attacker requires authentication with 'Custom' or higher privileges (possessing the `edit_docs` capability). For the exploit to succeed, a multilingual plugin like WPML or Polylang must be active on the target site. The attacker includes a malicious SQL payload in the 'lang' query parameter. This parameter is used by the plugin to modify the term query without proper sanitization or use of $wpdb->prepare, allowing for information disclosure via time-based or boolean-based SQL injection.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.