CVE-2026-8679

AudioIgniter Music Player <= 2.0.2 - Unauthenticated Insecure Direct Object Reference to 'audioigniter_playlist_id' Parameter

highAuthorization Bypass Through User-Controlled Key
7.5
CVSS Score
7.5
CVSS Score
high
Severity
2.0.3
Patched in
1d
Time to patch

Description

The AudioIgniter plugin for WordPress is vulnerable to Insecure Direct Object Reference in versions up to, and including, 2.0.2. This is due to the handle_playlist_endpoint() function (hooked to template_redirect) accepting a user-controlled playlist ID via the audioigniter_playlist_id query var or the /audioigniter/playlist/{id}/ rewrite rule and returning playlist track data without performing any authentication, capability, or post_status check — only the post_type is validated. This makes it possible for unauthenticated attackers to view track metadata (titles, artists, audio URLs, buy links, download URLs, and cover images) of any playlist on the site, including those in draft, private, pending, or trash status.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=2.0.2
PublishedMay 21, 2026
Last updatedMay 22, 2026
Affected pluginaudioigniter

What Changed in the Fix

Changes introduced in v2.0.3

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-8679 (AudioIgniter Music Player) ## 1. Vulnerability Summary The **AudioIgniter Music Player** plugin (<= 2.0.2) contains an **Insecure Direct Object Reference (IDOR)** vulnerability within its playlist data endpoint. The function `handle_playlist_endpoint()`,…

Show full research plan

Exploitation Research Plan: CVE-2026-8679 (AudioIgniter Music Player)

1. Vulnerability Summary

The AudioIgniter Music Player plugin (<= 2.0.2) contains an Insecure Direct Object Reference (IDOR) vulnerability within its playlist data endpoint. The function handle_playlist_endpoint(), which is hooked to template_redirect, allows unauthenticated users to retrieve metadata for any playlist by providing its ID. Because the function only validates that the requested ID corresponds to the ai_playlist post type and fails to verify the post_status (e.g., draft, private, trash) or user permissions, it exposes sensitive track information (URLs, titles, download links) that should not be publicly accessible.

2. Attack Vector Analysis

  • Endpoints:
    1. /?audioigniter_playlist_id=[ID] (Query parameter)
    2. /audioigniter/playlist/[ID]/ (Rewrite rule)
  • Parameter: audioigniter_playlist_id
  • Authentication: None required (Unauthenticated).
  • Preconditions:
    • The plugin must be active.
    • A playlist must exist (even if it is a draft, private, or in the trash).
  • Severity: High (7.5) - This allows full disclosure of track metadata and audio source URLs for restricted content.

3. Code Flow

  1. Registration: In audioigniter.php, the method init() (line 144) calls register_playlist_endpoint(), which registers the audioigniter_playlist_id query variable and a corresponding rewrite rule.
  2. Hooking: In audioigniter.php, the method frontend_init() (line 197) hooks handle_playlist_endpoint() to the template_redirect action.
  3. Processing (Inferred): When a request is made:
    • template_redirect triggers handle_playlist_endpoint().
    • The function retrieves the ID from get_query_var( 'audioigniter_playlist_id' ).
    • It calls get_post( $id ).
    • It checks if ( $post->post_type === 'ai_playlist' ).
    • Vulnerability: It proceeds to output the playlist's track data (stored in post meta) as JSON and exits, without checking if post_status is 'publish'.

4. Nonce Acquisition Strategy

According to the vulnerability description, the handle_playlist_endpoint() function performs no authentication or capability checks. This includes a lack of nonce verification.

  • Nonce Requirement: None. The endpoint is intended to be a public data source for the player's JavaScript component, but it fails to restrict access to non-public playlists.

5. Exploitation Strategy

The goal is to retrieve track metadata from a Draft playlist as an unauthenticated user.

  1. Preparation: Identify or create a playlist in draft status.
  2. Request: Send a GET request to the site using the audioigniter_playlist_id parameter.
  3. Extraction: Parse the JSON response to confirm track titles, audio URLs, and download links are present.

Targeted Request

GET /?audioigniter_playlist_id=[PLAYLIST_ID] HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0
Accept: application/json

6. Test Data Setup

Use wp-cli to create the vulnerable state:

  1. Create a Draft Playlist:

    wp post create --post_type=ai_playlist --post_status=draft --post_title="Secret Album 2026" --post_content="Draft content"
    

    Note the returned ID (e.g., 123).

  2. Add Track Metadata:
    The plugin stores tracks in serialized post meta. Based on the source fields (lines 540-622), the metadata usually resides in a key like _audioigniter_tracks.

    wp post meta update 123 _audioigniter_tracks '[{"title":"Unreleased Track","artist":"The Attacker","audio":"https://example.com/secret.mp3","download_url":"https://example.com/download-secret"}]' --format=json
    

7. Expected Results

A successful exploit will return a 200 OK response with a JSON body similar to:

[
  {
    "title": "Unreleased Track",
    "artist": "The Attacker",
    "audio": "https://example.com/secret.mp3",
    "download_url": "https://example.com/download-secret",
    ...
  }
]

The response confirms that metadata for a draft post is leaked.

8. Verification Steps

  1. Confirm Post Status: Use WP-CLI to verify the playlist is indeed not published.
    wp post get [PLAYLIST_ID] --field=post_status
    # Expected: draft
    
  2. Verify Unauthenticated Access: Ensure the HTTP request was made without any session cookies or Authorization headers.

9. Alternative Approaches

If the query parameter method fails due to specific server configurations:

  • Rewrite Rule: Try the pretty permalink structure:
    GET /audioigniter/playlist/[ID]/ HTTP/1.1
  • Internal Query: If the endpoint is restricted by security plugins, try accessing via admin-ajax.php if the plugin registered an alternative handler there (though the description points specifically to template_redirect).
  • Metadata Hunting: If track data isn't in the response, check if the response returns a list of attachment IDs, which could then be queried individually. (The description implies metadata is returned directly).
Research Findings
Static analysis — not yet PoC-verified

Summary

The AudioIgniter plugin for WordPress is vulnerable to an Insecure Direct Object Reference (IDOR) via its playlist data endpoint. Unauthenticated attackers can retrieve sensitive track metadata, including audio URLs and download links, for playlists that are in draft, private, or trash status by providing a numeric ID through the 'audioigniter_playlist_id' parameter.

Vulnerable Code

// audioigniter.php:1266
	public function handle_playlist_endpoint() {
		$playlist_id = get_query_var( 'audioigniter_playlist_id' );

		if ( empty( $playlist_id ) ) {
			return;
		}

		$playlist_id = intval( $playlist_id );
		$post        = get_post( $playlist_id );

		if ( empty( $post ) || $post->post_type !== $this->post_type ) {
			wp_send_json_error( __( "ID doesn't match a playlist", 'audioigniter' ) );
		}

		$response = array();
		$tracks   = $this->get_post_meta( $playlist_id, '_audioigniter_tracks', array() );

		// ... [processing tracks] ...

		wp_send_json( $response );
	}

---

// audioigniter.php:1217
		$post = get_post( $id );

		$params = apply_filters( 'audioigniter_shortcode_data_attributes_array', $this->get_playlist_data_attributes_array( $id ), $id, $post, $atts );

Security Fix

--- /home/deploy/wp-safety.org/data/plugin-versions/audioigniter/2.0.2/audioigniter.php	2025-09-16 12:14:36.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/audioigniter/2.0.3/audioigniter.php	2026-05-15 21:01:12.000000000 +0000
@@ -6,7 +6,7 @@
  * Author: The CSSIgniter Team
  * Author URI: https://www.cssigniter.com
  * License: GPLv2 or later
- * Version: 2.0.2
+ * Version: 2.0.3
  * Text Domain: audioigniter
  * Domain Path: /languages
  *
@@ -1208,7 +1208,7 @@
 			'class' => '',
 		), $atts, $tag );
 
-		$id         = intval( $atts['id'] );
+		$id         = (int) $atts['id'];
 		$class_name = $atts['class'];
 
 		if ( ! $this->is_playlist( $id ) ) {
@@ -1217,6 +1217,13 @@
 
 		$post = get_post( $id );
 
+		if ( $post->post_status == 'trash' ||
+		     ( ! is_user_logged_in() && 'publish' !== $post->post_status ) ||
+		     ( is_user_logged_in() && ! current_user_can( 'read_post', $id ) ) ) {
+			return '';
+		}
+
+
 		$params = apply_filters( 'audioigniter_shortcode_data_attributes_array', $this->get_playlist_data_attributes_array( $id ), $id, $post, $atts );
 		$params = array_filter( $params, array( $this->sanitizer, 'array_filter_empty_null' ) );
 		$params = $this->sanitizer->html_data_attributes_array( $params );
@@ -1266,12 +1273,17 @@
 			return;
 		}
 
-		$playlist_id = intval( $playlist_id );
+		$playlist_id = (int) $playlist_id;
 		$post        = get_post( $playlist_id );
 
 		if ( empty( $post ) || $post->post_type !== $this->post_type ) {
 			wp_send_json_error( __( "ID doesn't match a playlist", 'audioigniter' ) );
 		}
+		if ( ( ! is_user_logged_in() && 'publish' !== $post->post_status ) ||
+			( is_user_logged_in() && ! current_user_can( 'read_post', $playlist_id ) )
+		) {
+			wp_send_json_error( __( 'Sorry, you are not allowed to access this playlist.', 'audioigniter' ) );
+		}
 
 		$response = array();
 		$tracks   = $this->get_post_meta( $playlist_id, '_audioigniter_tracks', array() );

Exploit Outline

To exploit this vulnerability, an unauthenticated attacker can perform the following steps: 1. Identify the target site using the AudioIgniter plugin. 2. Craft a GET request to the site's root using the query parameter 'audioigniter_playlist_id' followed by the ID of a suspected non-public playlist (e.g., `/?audioigniter_playlist_id=123`). Alternatively, use the permalink structure `/audioigniter/playlist/[ID]/` if rewrite rules are active. 3. No authentication, nonces, or cookies are required for this request. 4. Analyze the JSON response, which will contain the serialized track metadata (including audio source URLs, download links, and artist names) even if the playlist's post status is 'draft', 'private', or 'pending'.

Check if your site is affected.

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