LearnPress to wtyczka LMS do WordPressa z ponad 70 tysiącami aktywnych instalacji. Według rekordu Wordfence z 17 października 2026 w wersjach do 4.4.10 włącznie niezalogowany użytkownik może w procesie zakupu przekazać wartość, która trafia do sesji i jest potem deserializowana bez ograniczenia klas. Ocena 9.8 zakłada pełny wpływ na poufność, integralność i dostępność. Przy PHP Object Injection to jednak sufit: realny skutek zależy od tego, jakie klasy są załadowane w danej instalacji. Do tego dochodzi drobny, ale ważny dla VM szczegół: w kodzie wersji 4.4.10 ograniczenie klas już jest, a rekord nadal ją obejmuje.
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H, CWE-502. Brak oceny NVD.exploitation: none, automatable: yes, technical impact: total. EPSS 0,44% (22.10.2026). Nie znalazłem publicznego PoC ani opisu łańcucha gadżetów.Mechanizm w jednym akapicie
Opis CNA jest konkretny. Parametr checkout-email z akcji AJAX procesu zakupu przechodzi przez sanitize_text_field(), która nie usuwa składni serializacji PHP. Wartość jest zapisywana w tabeli sesji LearnPress, a przy kolejnych żądaniach LP_Session_Handler::get() przekazuje ją do LP_Helper::maybe_unserialize() i dalej do unserialize() bez allowed_classes. Ciąg znaków z przeglądarki staje się więc obiektem PHP po stronie serwera. To klasyczny błąd granicy zaufania: dane zapisane jako tekst są później traktowane jak zaufany, zserializowany stan.
9.8 to sufit, nie opis Twojej instalacji
Szkic VMRT Radar trafnie to zaznaczał: PHP Object Injection nie oznacza automatycznie zdalnego wykonania kodu. Wstrzyknięty obiekt coś robi tylko wtedy, gdy w procesie PHP jest załadowana klasa, której metody magiczne (np. __destruct, __wakeup, __toString) wykonują z jego właściwościami coś niebezpiecznego. Taki zestaw klas to łańcuch gadżetów (POP chain). Wordfence w opisie nie wskazuje łańcucha w samym LearnPress ani w rdzeniu WordPressa. Ocena C:H/I:H/A:H zakłada najgorszy przypadek, w którym łańcuch istnieje w którejś z innych wtyczek lub motywów.
Dla VM wynikają z tego dwie rzeczy:
- Nie obniżaj priorytetu dlatego, że „nie ma łańcucha”. Łańcuch zależy od Twojego zestawu wtyczek, a portale kursowe mają ich zwykle sporo: bramki płatności, page buildery, integracje mailingowe. Brak publicznego łańcucha to brak wiedzy, a nie brak ryzyka. Atak nie wymaga konta i według SSVC CISA daje się zautomatyzować. Takie kombinacje w ekosystemie WordPressa potrafią przejść od diffa do exploita w ciągu godzin, co opisywałem przy CVE-2026-87902.
- Nie podnoś też komunikacji do „RCE bez logowania”. W raporcie dla właściciela aplikacji napisz: deserializacja niezaufanych danych bez uwierzytelnienia, skutek od zera do wykonania kodu w zależności od zainstalowanych komponentów. Różnicę między przerwanym łańcuchem a usuniętą podatnością omawiałem przy Kalturze.
Rekord kontra kod: co jest w 4.4.10
Referencje w rekordzie CVE prowadzą do kodu z tagu 4.4.9.1. Porównałem w SVN WordPress.org funkcję LP_Helper::maybe_unserialize() w trzech tagach:
| Wersja (data) | Rekord CVE | LP_Helper::maybe_unserialize() w SVN | Changelog |
|---|---|---|---|
| 4.4.9.1 (01.10.2026) | Podatna; do tego tagu odsyłają referencje rekordu | Woła maybe_unserialize() z WordPressa, bez ograniczenia klas | Poprawki funkcjonalne |
| 4.4.10 (09.10.2026) | Podatna („up to, and including, 4.4.10”) | unserialize(..., ['allowed_classes' => false]) po is_serialized() | „Fixed: security (Props @Wordfence, … @Wordfence PRISM …)” |
| 4.4.11 (16.10.2026) | Pierwsza poza zakresem | Jak w 4.4.10 | „Fixed: security (Props @Wordfence, @Patchstack, …)” |
W tagu 4.4.10 (plik z 09.10.2026) funkcja deserializuje już z allowed_classes => false, czyli nie tworzy obiektów dowolnych klas. W liniach, które sprawdziłem (zapis checkout-email do sesji i get() w obsłudze sesji), kod 4.4.10 i 4.4.11 jest taki sam. Changelog 4.4.10 dziękuje m.in. „@Wordfence PRISM”, a to zgłaszający tego CVE. Oś czasu też pasuje: vendor powiadomiony 2 października, wydanie 4.4.10 dziewiątego.
Najprostsze wyjaśnienie: główna poprawka weszła już w 4.4.10, a Wordfence wyznaczył granicę ostrożnie albo mapuje CVE na zmianę z 4.4.11 (rekord odsyła do changesetu 3750024 z dnia wydania 4.4.11). Możliwe też, że w 4.4.10 została inna ścieżka, której nie znalazłem. Nie rozstrzygam tego: niepotwierdzone. Ważniejsza jest decyzja procesowa:
- Nie zamykaj findingu dla 4.4.10 na podstawie własnej lektury kodu. Grep kilku plików to nie analiza wszystkich ścieżek deserializacji. Skanery i audytorzy będą trzymać się rekordu, więc wyjątek „4.4.10 jest w praktyce poprawiona” wymaga potwierdzenia od producenta albo Wordfence.
- Możesz natomiast uwzględnić to przy priorytecie wewnątrz kolejki. Instalacje < 4.4.10 (bez ograniczenia klas w helperze) są pilniejsze niż 4.4.10. Cel dla wszystkich to i tak 4.4.11.
- Zgłoś rozjazd. Pytanie do Wordfence lub ThimPress, który commit zamyka CVE-2026-104736, kosztuje jeden mail i porządkuje dane dla wszystkich.
Mapowanie „Fixed: security” na konkretne CVE to w ekosystemie wtyczek WordPressa raczej reguła niż wyjątek. Oba ostatnie wydania LearnPress mają w changelogu tylko listę podziękowań, a 4.4.11 dziękuje też Patchstack i kilku badaczom. Wersja 4.4.11 prawdopodobnie zamyka więc także inne, jeszcze nieopublikowane zgłoszenia. To dodatkowy argument, żeby celem była najnowsza wersja, a nie minimalna z rekordu.
Co powinien zrobić VE
- Znajdź instalacje LearnPress, w tym portale klientów, kopie stagingowe i stare instancje marketingowe. Zapisz wersję wtyczki z działającej instancji i to, czy proces zakupu jest publicznie dostępny.
- Aktualizuj do 4.4.11 lub nowszej. Przy < 4.4.10 traktuj to jako pilne. Przetestuj na stagingu bramki płatności, motyw i dodatki LearnPress, bo oba ostatnie wydania zmieniały też UI.
- Jeśli aktualizacja musi poczekać, regułą WAF możesz blokować wartości o składni serializacji PHP w parametrach procesu zakupu (wiele WAF ma takie sygnatury). To mitigacja, nie dowód usunięcia błędu, i nie obejmuje wartości już zapisanych w sesji.
- Przejrzyj tabelę sesji i logi: wartości
checkout-email, które nie wyglądają jak adres e-mail, błędy PHP zunserialize()i__PHP_Incomplete_Class, nieoczekiwane pliki i konta administratorów. Nie testuj produkcji ładunkami deserializacji. - Zamknij finding po potwierdzeniu wersji ≥ 4.4.11 w działającej instancji i poprawnego działania sklepu. Rozjazd dla 4.4.10 zanotuj w findingu, dopóki producent go nie wyjaśni.
Powiązane na blogu
- WordPress CVE-2026-87902 — od patch diffa do exploita w kilka godzin
- Kaltura Player V2 — przerwany łańcuch to nie usunięta podatność
- Wtyczka płatności CVE-2026-16947 — CWE ukrywa biznesowy skutek w procesie zakupu
- WordPress CVE-2026-93485 — atak bez logowania na publiczną funkcję
Źródła
- CVE.org — CVE-2026-104736 (CNA Wordfence, CVSS 3.1 9.8, CWE-502, zakres do 4.4.10, oś czasu, zgłaszający Wordfence PRISM) — cve.org
- NVD — CVE-2026-104736 (status Deferred, SSVC CISA) — nvd.nist.gov
- Wordfence Intelligence — wpis podatności (odnośnik z rekordu CVE) — wordfence.com
- WordPress.org — LearnPress (wersja 4.4.11 z 16.10.2026, changelog 4.4.10 i 4.4.11, liczba instalacji) — wordpress.org
- WordPress.org SVN — tagi LearnPress (inc/class-lp-helper.php w 4.4.9.1, 4.4.10, 4.4.11) — plugins.svn.wordpress.org
- PHP — unserialize() i opcja allowed_classes — php.net
- CISA Known Exploited Vulnerabilities Catalog (brak CVE-2026-104736 w wersji 2026.10.21) — cisa.gov
Nota redakcyjna: wpis powstał na podstawie szkicu VMRT Radar z 19.10.2026 i został zweryfikowany ze źródłami pierwotnymi 20 października 2026 (ok. 19:10 CEST): rekord CVE.org (CNA Wordfence, CVSS 3.1 9.8, CWE-502, zakres do 4.4.10, oś czasu, zgłaszający), NVD API 2.0 (status „Deferred”, SSVC CISA), API wtyczek WordPress.org (wersja, data, changelog, liczba instalacji), pliki w SVN WordPress.org dla tagów 4.4.9.1, 4.4.10 i 4.4.11, EPSS i katalog CISA KEV 2026.10.16. Strona Wordfence Intelligence nie była dostępna z mojego środowiska. Względem szkicu doprecyzowałem CVSS (9.8, wektor), CWE, zgłaszającego, oś czasu i dodałem obserwację o ograniczeniu klas w kodzie 4.4.10. Ponownie 22 października 2026 (ok. 22:40 CEST) sprawdziłem katalog CISA KEV (wersja 2026.10.21: nadal brak wpisu), EPSS (bez zmian) oraz wersje w PyPI, GitHub i WordPress.org (bez nowych wydań). Nie potwierdziłem: którą zmianę Wordfence mapuje na to CVE, czy 4.4.10 jest nadal podatna inną ścieżką, czy istnieje łańcuch gadżetów w LearnPress lub typowych wtyczkach, ani czy błąd był wykorzystywany. Interpretacja rozjazdu rekordu z kodem i priorytetyzacja to oceny autora.