CVE-2026-104736: LearnPress checkout-email Is Unauth Object Injection - Floor 4.4.11

The Situation
ThimPress LearnPress (learnpress on wordpress.org) is the LMS plugin that turns a WordPress site into a course catalog with a checkout AJAX path. Wordfence published CVE-2026-104736 on 17 October 2026 (datePublished 2026-10-17T03:43:28.046Z). CVE.org JSON is PUBLISHED, assigner Wordfence. Title, theirs: “LearnPress <= 4.4.10 - Unauthenticated PHP Object Injection via 'checkout-email' Parameter.” Description, theirs not ours: the checkout-email request parameter on the checkout AJAX action is passed through sanitize_text_field(), stored in the LearnPress session table, then fed to LP_Helper::maybe_unserialize() → unserialize() without an allowed_classes restriction on a later request. CWE-502. Credit: Wordfence PRISM. Timeline in the same record: vendor notified 2026-10-02T12:07:17Z, disclosed 2026-10-16T14:33:32Z.[1][2][3]
Wordfence CVSS 3.1 is 9.8 CRITICAL: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H. Privileges required: NONE. NVD vulnStatus this morning is Received; NIST has not published its own 3.1. CISA-ADP SSVC on the same object: exploitation none, automatable yes, technical impact total (timestamp 2026-10-18T11:08:40Z).[2][3]
Wordfence Intelligence names the floor: update to 4.4.11 or newer. Affected: ≤ 4.4.10. wordpress.org plugin API this morning: current version 4.4.11, last_updated 2026-10-16 11:24am GMT, 70,000 active_installs. Changelog line for 4.4.11: “Fixed: security (Props @Wordfence, @Patchstack, @Ananda Dhakal, @daroo, @MD Mahmidul Hasan).” 4.4.10 (2026-10-09) already had a security line crediting @Wordfence PRISM.[1][4]
CISA KEV catalog 2026.10.16 (count 1748, dateReleased 2026-10-16T17:15:48.8752Z) does not list CVE-2026-104736. Newest dateAdded rows are still BeyondTrust CVE-2026-102764 and Fortinet CVE-2025-61624 - not WordPress.[7]
What the bug actually is
PHP object injection (CWE-502) means attacker-controlled serialized PHP is passed to unserialize(). If a POP gadget exists in the process, that becomes file write / RCE / whatever the gadget does. Wordfence stops at unauthenticated, inject a PHP object. They do not name a gadget in LearnPress or claim they saw RCE.[1][2]
SVN tags we pulled today (plugins.svn.wordpress.org):
- 4.4.9.1
LP_AJAX::init()registerscheckout:nopriv- WordPress will run that AJAX action for visitors who are not logged in. CVE reference is this file, line 21.[5] - 4.4.9.1
LP_Checkout::process_checkout_handler()readsLP_Request::get_param( 'checkout-email' ). Default$sanitize_typeinget_param()is'text', which is thesanitize_text_field()path Wordfence named. If the value is non-empty it issession->set( 'checkout-email', … ).[6][8] - 4.4.9.1
LP_Session_Handler::get()returnsLP_Helper::maybe_unserialize( $this->_data[ $key ] ). In 4.4.9.1 / 4.4.8 that helper calls WordPressmaybe_unserialize()(noallowed_classesargument in the plugin wrapper). In 4.4.10 and 4.4.11 the helper instead calls@unserialize( $string, array( 'allowed_classes' => false ) )after anis_serialized()check.[9][10] - 4.4.10 checkout already uses
get_param( 'checkout-email', '', 'email' ). 4.4.11 vs 4.4.10 on that file isorder_commentsswitched to'textarea'- not the email field. That matches a different same-week Wordfence record (CVE-2026-109208, unauthenticated stored XSS viaquantity/order_comments), not this POI.[1][6]
So: Wordfence's mechanism sentence matches 4.4.9.1. The 4.4.10 tag we fetched already locks classes and email-sanitizes the parameter. Wordfence still lists 4.4.10 as affected and 4.4.11 as the patch. Treat 4.4.11 as the floor because that is the CNA's patched version, and 4.4.11 also carries the other 16 Oct security credits. Do not argue with a scanner that flags 4.4.10.[1][4][10]
What nobody published in the CVE record:
- A POP chain inside LearnPress, or a named gadget in a common add-on (WooCommerce gateway, certificates, assignments).
- In-the-wild use. CISA-ADP is exploitation none as of 18 Oct.[2]
- Whether
sanitize_text_field()on a craftedO:…blob still leaves a stringis_serialized()accepts. Wordfence says it does not strip serialized object syntax; we did not fuzz it.[1]
Do not treat 9.8 as “every LearnPress site is RCE.” Do not treat “object injection” as proven code execution. The published claim is: an unauthenticated POST to the LearnPress checkout AJAX can plant a serialized object in the session, and on ≤ 4.4.9.1 that session is unserialized without a class allow-list.[1][2][5][9]
We did not send a payload. There is no public PoC in the CVE references - Wordfence advisory + Trac tags + one changeset URL.[2][3]
Hunt the fleet - version, then bump the plugin
Inventory is the plugin file, not a panel build:
# one site (wp-cli)
wp plugin get learnpress --field=version --path=/home/USER/public_html
# cPanel box, every account (slow, read-only)
find /home -path '*/wp-content/plugins/learnpress/learnpress.php' 2>/dev/null \
| while read -r f; do
ver=$(awk -F': ' '/^[[:space:]]*\*[[:space:]]*Version:/{print $2; exit}' "$f")
echo "$ver $f"
done
Floor:
wp plugin update learnpress --path=/home/USER/public_html
wp plugin get learnpress --field=version --path=/home/USER/public_html
# expect 4.4.11 or newer
No wp-cli: Dashboard → Plugins → LearnPress → update, or drop in the 4.4.11 zip from wordpress.org. Do not leave a site on 4.4.10 just because the helper looks patched in SVN - Wordfence's affected range includes it, and 4.4.11 is the release that closed the rest of the 16 Oct batch.[1][4]
Until the floor is on disk:
- The AJAX action is
checkout:nopriv. A WAF rule that only checksadmin-ajax.phpfor logged-in users will miss it. We are not publishing a signature; there is no vendor virtual patch named in the advisory.[1][5] - Disable LearnPress checkout / take the course catalog off paid enrollment only if you cannot update today. That is an availability trade, not a patch.
- A WordPress firewall is not a version bump.
After 4.4.11: this patch does not rewind a site that was already owned. Look for unexpected Administrator users, unexpected plugins, and wp_lp_sessions rows around 2-17 October 2026. We have no IOC list from Wordfence.[1][2]
Honesty / What We Could Not Verify
- We did not exploit this. No serialized payload, no
admin-ajax.phpPOST, no gadget hunt. - Object injection is not RCE by itself. Wordfence's 9.8 is C/H I/H A/H with no POP chain in the advisory. CISA-ADP still labels technical impact total. We are not inventing a gadget to match the score.[1][2]
- 4.4.10 tag vs Wordfence affected range disagree on the sink. SVN 4.4.10 already has
allowed_classes => falseand'email'sanitization oncheckout-email. Floor remains 4.4.11 because that is what the CNA published.[1][4][10] - 4.4.11 changelog does not name CVE-2026-104736. It is a generic “Fixed: security” line with five researcher handles. It also covers other 16 Oct LearnPress CVEs (at least CVE-2026-109208 XSS). Do not map every credit to this one bug.[1][4]
- Not on CISA KEV as of catalog 2026.10.16 / count 1748.[7]
- CISA-ADP SSVC: exploitation none. We are not inventing in-the-wild use.[2]
- NVD status Received - no NIST 3.1 yet. The 9.8 is Wordfence.[2]
- 70,000 active_installs is wordpress.org's API figure this morning, not a count of vulnerable copies.[4]
What this is not
- Not CVE-2026-104798 (My Calendar unauth PHP dispatch). Different plugin.
- Not CVE-2026-87902 (WordPress Core RFI, KEV 25 Sep). Core, not LearnPress.
- Not CVE-2026-105474 (SolusVM 2 SSTI). Virt panel, not WordPress.
- Not today's KEV (BeyondTrust Remote Support, Fortinet path traversal).
- Not “every LMS on the box is owned.” Need LearnPress ≤ 4.4.10 per Wordfence, and a reachable checkout AJAX.
- Not a cPanel/WHM bug. Patch the plugin;
upcpwill not bump it.
Sources
[1] https://www.wordfence.com/threat-intel/vulnerabilities/id/3e28e008-0ec1-4262-9ac0-6170cf8b8bdf?source=cve - Wordfence Intelligence CVE-2026-104736
[2] https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2026-104736 - NVD REST CVE-2026-104736
[3] https://cveawg.mitre.org/api/cve/CVE-2026-104736 - CVE.org JSON CVE-2026-104736
[4] https://wordpress.org/plugins/learnpress/ - LearnPress 4.4.11 plugin page / changelog (API last_updated 2026-10-16 11:24am GMT)
[5] https://plugins.trac.wordpress.org/browser/learnpress/tags/4.4.9.1/inc/class-lp-ajax.php#L21 - checkout:nopriv AJAX registration
[6] https://plugins.trac.wordpress.org/browser/learnpress/tags/4.4.9.1/inc/class-lp-checkout.php#L377 - process_checkout_handler / checkout-email
[7] https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json - CISA KEV JSON catalog 2026.10.16
[8] https://plugins.svn.wordpress.org/learnpress/tags/4.4.9.1/inc/class-lp-request-handler.php - get_param() default $sanitize_type = 'text'
[9] https://plugins.trac.wordpress.org/browser/learnpress/tags/4.4.9.1/inc/class-lp-session-handler.php#L373 - LP_Session_Handler::get() → maybe_unserialize
[10] https://plugins.svn.wordpress.org/learnpress/tags/4.4.10/inc/class-lp-helper.php - 4.4.10 helper unserialize(..., allowed_classes => false)