Points Management System For Gamification, Ranks, Badges, and Loyalty Rewards Program – myCred <= 3.0.4 - Authenticated (Subscriber+) Stored Cross-Site Scripting
Description
The Points Management System For Gamification, Ranks, Badges, and Loyalty Rewards Program – myCred plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 3.0.4 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with subscriber-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:NTechnical Details
What Changed in the Fix
Changes introduced in v3.0.5
Source Code
WordPress.org SVNI cannot fulfill this request. I am prohibited from generating actionable exploitation research plans, specific attack payloads, or technical instructions for exploiting vulnerabilities in specific software. For information on how to identify and remediate security vulnerabilities in WordPress plug…
Show full research plan
I cannot fulfill this request. I am prohibited from generating actionable exploitation research plans, specific attack payloads, or technical instructions for exploiting vulnerabilities in specific software.
For information on how to identify and remediate security vulnerabilities in WordPress plugins, you may find the following resources helpful:
- WordPress Plugin Handbook (Security Section): Provides official guidance on data validation, sanitization, and escaping to prevent Cross-Site Scripting (XSS) and other common vulnerabilities.
- OWASP Cross-Site Scripting (XSS) Prevention Cheat Sheet: Offers comprehensive best practices for defending against XSS in various web development contexts.
- Common Vulnerabilities and Exposures (CVE) Database: Useful for tracking reported vulnerabilities and understanding the technical details of patches.
If you are a developer looking to secure your code, ensure that all user-supplied data is strictly sanitized before storage and properly escaped for the specific output context (HTML, JavaScript, or attributes) using WordPress functions like esc_html(), esc_attr(), and wp_kses_post(). For data rendered within JavaScript contexts, such as template literals, extra care must be taken to prevent breakout characters like backticks or ${} expressions.
Summary
The myCred plugin for WordPress is vulnerable to Stored Cross-Site Scripting via its notifications system. Authenticated users can trigger actions that generate log entries containing malicious JavaScript, which is then stored and executed in the browser when the plugin renders notifications using insecure JavaScript template literals in the footer.
Vulnerable Code
// addons/notifications/myCRED-addon-notifications.php:74 foreach ( (array) $notices as $notice ) { $notice = str_replace( array( "\r", "\n", "\t" ), '', $notice ); echo '<!-- Notice --><script type="text/javascript">(function(jQuery){jQuery.noticeAdd({ text: `' . wp_kses_post( $notice ) . '`,stay: ' . esc_js( $stay ) . '});})(jQuery);</script>'; }
Security Fix
@@ -73,11 +73,17 @@ // Loop Notifications foreach ( (array) $notices as $notice ) { - $notice = str_replace( array( "\r", "\n", "\t" ), '', $notice ); - echo '<!-- Notice --><script type="text/javascript">(function(jQuery){jQuery.noticeAdd({ text: `' . wp_kses_post( $notice ) . '`,stay: ' . esc_js( $stay ) . '});})(jQuery);</script>'; + $notice = wp_kses_post( wp_unslash( $notice ) ); + $encoded_notice = wp_json_encode( $notice, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT ); + + if ( false === $encoded_notice ) { + continue; + } + + echo '<!-- Notice --><script type="text/javascript">(function(jQuery){jQuery.noticeAdd({ text: ' . $encoded_notice . ',stay: ' . esc_js( $stay ) . '});})(jQuery);</script>'; }
Exploit Outline
1. An authenticated attacker identifies a feature that awards points and allows user-controlled input to appear in the point log entry (e.g., a comment, a referral string, or a custom action label). 2. The attacker submits a payload designed to break out of a JavaScript template literal (backticks) or utilize `${}` interpolation, such as `${alert(document.domain)}`. 3. The plugin processes the point award and generates a notification message based on the configured template (often using the `%entry%` tag, which contains the malicious log entry). 4. This notification is stored in a WordPress transient for the user (`mycred_notice_{user_id}`). 5. When the user (or any user targeted by the point action) visits a page where the plugin renders notifications, the `wp_footer` hook executes and echoes the malicious payload directly into a `<script>` block without proper JavaScript escaping, leading to script execution.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.