LearnPress Guest Checkout POI (CVE-2026-104736): lp-ajax checkout-email and maybe_unserialize
Admin · October 22, 2026 · 60 views
Guest checkout should not deserialize attacker data
LearnPress is a widely deployed WordPress LMS plugin. CVE-2026-104736 is unauthenticated PHP object injection (CWE-502, CVSS 9.8 Critical) in guest checkout handling: the plugin stores checkout-email from lp-ajax=checkout in the session, then reads it through LP_Helper::maybe_unserialize() — classic POP when gadgets exist on the site.
Public PoC: CVE-2026-104736 on pocbit.org. Repository: murrez/CVE-2026-104736. Fixed in 4.4.11+.
| | |
|---|---|
| Affected | ≤ 4.4.10 |
| Fixed | 4.4.11+ |
| Auth | None — wp_ajax_nopriv_* checkout path |
| Entry | POST with lp-ajax=checkout, field checkout-email |
| Impact | Object injection → RCE when WordPress/plugin gadget chains exist |
Why this is not “just another admin-ajax bug”
LearnPress routes many actions through lp-ajax on the front-end URL, not only admin-ajax.php?action=. Defenders who monitor action=learnpress_* in admin-ajax logs may miss guest checkout traffic entirely.
Mechanism in plain terms:
- Unauthenticated user hits checkout AJAX (guest flow).
- Plugin writes
checkout-email(and related session keys) from the request. - Later code paths unserialize session values via
maybe_unserialize(). - Attacker supplies a serialized PHP object instead of an email string → POP / property-oriented exploitation.
4.4.10 may apply sanitize_email() to checkout-email, which can strip raw serialized blobs — treat “maybe blocked on latest 4.4.x” as lab-verified, not assumed safe. The bundled CHAINS.md documents phpggc / chain research for authorized labs.
Cross-read: WordPress security checklist 2026, file upload and injection surfaces, safe PoC lab setup.
Defender checklist
| # | Action | Detail |
|---|--------|--------|
| 1 | Version | Plugins screen or readme.txt — target ≥ 4.4.11 |
| 2 | Upgrade | Staging first; snapshot DB; retest paid courses / guest checkout |
| 3 | WAF / logs | Alert on lp-ajax=checkout POSTs with O:, a:, s: patterns in checkout-email |
| 4 | Reduce POP | Remove unused plugins; fewer classes → fewer gadgets (supply chain) |
| 5 | Inventory | Any site with LearnPress + WooCommerce-style checkout — prioritize internet-facing LMS |
| 6 | Validate | Authorized poc.py --mode check then controlled exploit in lab only |
python poc.py --mode check -u https://lab.local
python poc.py -u https://lab.local
python poc.py -f targets.example.txt --mode check -j 20
Patch validation (lab)
- WordPress + LearnPress 4.4.10 (vulnerable pin) in isolated VM.
- Confirm plugin version with
checkmode (readme fingerprint). - Run exploit chain with harmless stdClass probe per README before any RCE chain.
- Upgrade to 4.4.11; repeat — session should not deserialize attacker-controlled objects from
checkout-email.
Discovery hints (your assets only)
body="learnpress" || body="lp-ajax"
http.component:"WordPress" && body:"LearnPress"
Hits are candidates — confirm version and business use of LearnPress checkout.
FAQ
Is this SQLi or XSS?
Neither primary class — it is PHP object injection via session deserialization. Impact still often becomes RCE on typical WordPress stacks.
Do we need a logged-in student?
No. The advisory path is guest checkout (nopriv), which is why CVSS stays 9.8 with AV:N.
WAF enough?
Serialization signatures help as defense in depth; upgrade LearnPress is the durable fix.
Same site as WooCommerce?
Many LMS sites run multiple commerce plugins — patch LearnPress specifically; do not assume WooCommerce hardening covers lp-ajax.
Bottom line
CVE-2026-104736 is a reminder that LMS guest checkout is high-value unauthenticated surface on WordPress. Upgrade to LearnPress 4.4.11+, log lp-ajax=checkout, and validate with the PoCbit bundle only in authorized environments.