SECURITY ADVISORY / 01

CVE-2024-8522 Exploit & Vulnerability Analysis

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

learnpress products NVD ↗
Exploit PoC Vulnerability Patch Analysis

The Exploit

An unauthenticated attacker can inject SQL into the LearnPress courses REST API by crafting a malicious c_only_fields parameter that breaks out of a comma-separated list context and appends arbitrary SQL.

curl -X GET 'http://vulnerable-site.local/wp-json/learnpress/v1/courses?c_only_fields=ID,post_title/**/UNION/**/SELECT/**/user_login,user_pass/**/FROM/**/wp_users--' \
  -H 'Content-Type: application/json'

The attacker observes the response includes user login credentials and password hashes in fields that should only contain course metadata. No authentication or capability check is required; the endpoint accepts requests from any origin.

What the Patch Did

Before

$fields         = explode( ',', $fields_str );
$filter->fields = $fields;

and

// c_only_fields parameter was not being processed at all

After

$fields         = explode( ',', $fields_str );
foreach ( $fields as $key => $field ) {
    $fields[ $key ] = LP_Database::getInstance()->wpdb->prepare( '%i', $field );
}
$filter->fields = $fields;

and

$fields_only_str = LP_Helper::sanitize_params_submitted( urldecode( $param['c_only_fields'] ?? '' ) );
if ( ! empty( $fields_only_str ) ) {
    $fields_only         = explode( ',', $fields_only_str );
    foreach ( $fields_only as $key => $field ) {
        $fields_only[ $key ] = LP_Database::getInstance()->wpdb->prepare( '%i', $field );
    }
    $filter->only_fields = $fields_only;
}

The patch introduced two security controls: first, it applies wpdb->prepare() with the %i placeholder (integer identifier) to every field name in both the c_fields and c_only_fields parameters. Second, it wraps the untrusted parameter value in LP_Helper::sanitize_params_submitted() before parsing, providing defence in depth. The %i placeholder tells WordPress to treat the string as a column identifier, not a literal SQL fragment, escaping special characters and preventing breakout.

Root Cause

This is a CWE-89 SQL Injection vulnerability. The attack path is: an unauthenticated HTTP request carries a c_only_fields query parameter → the REST controller at /wp-json/learnpress/v1/courses accepts it with minimal validation → the parameter value is split by commas but never escaped or parameterized → the field names are interpolated directly into a SQL query string built in inc/Models/Courses.php → an attacker injects SQL operators and SELECT clauses that the database interprets as valid SQL commands. The c_only_fields parameter explicitly landed in the codebase without sanitization logic, creating an unguarded entry point to the database layer.

Why It Works

The load-bearing line is LP_Database::getInstance()->wpdb->prepare( '%i', $field ). Without it, field names remain raw user input; with it, WordPress's prepared statement mechanism escapes SQL metacharacters and enforces identifier context. If you removed only this line but kept LP_Helper::sanitize_params_submitted(), the exploit would still work because basic HTML sanitization (likely htmlspecialchars() or strip_tags()) does not prevent SQL syntax. The engineer added the helper function call for defense in depth—to catch obvious attack signatures early—but the real blocker is prepare(). The foreach loop is necessary because prepare() operates on individual strings, not arrays; without the loop, the unsanitized array would pass through unchanged.

Hardening Checklist

  • Whitelist field names before query construction. Before splitting user input into field names, validate each against a hardcoded array of allowed columns using in_array( $field, $allowed_columns, true ). Do not rely on sanitization alone to prevent injection.

  • Use parameterized queries for all dynamic SQL. Always call $wpdb->prepare() with appropriate placeholders (%i for identifiers, %d for integers, %s for strings) instead of string concatenation, even for column names that seem "safe."

  • Apply nonce verification on REST endpoints. Add check_ajax_referer() or a custom nonce check in the REST controller callback to prevent CSRF and establish an authenticated context, even if the endpoint is public.

  • Escape and validate at REST controller entry. Use sanitize_text_field() or sanitize_key() on all query parameters in the REST controller before passing them to model/database layers. Do not rely on downstream sanitization as a security boundary.

  • Audit field-name handling across all REST endpoints. Search the codebase for explode() calls on user input, especially in REST callbacks. Any parameter that controls column selection, table names, or field lists must be whitelisted or parameterized.

References

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

Frequently asked questions about CVE-2024-8522

What is CVE-2024-8522?

CVE-2024-8522 is a security vulnerability identified in learnpress. 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-8522?

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

How does CVE-2024-8522 get exploited?

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

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

CVE-2024-8522 affects learnpress. 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-8522?

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

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

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