22. září 2026 byla zveřejněna kritická zranitelnost v jádru WordPressu, CVE-2026-87902. Ještě téhož večera začaly na weby chráněné WEDOS Global Protection (WGP) přicházet první škodlivé požadavky. V článku popisujeme, jak útok vypadal v datech, jak jsme ho odlišili od běžného provozu a proč jsme místo čekání na aktualizace jednotlivých webů nasadili pravidlo na aplikační vrstvě (WAF).
Co je CVE-2026-87902
Jde o chybu typu path traversal v jádru WordPressu. Útočník ji zneužívá přes dva standardní parametry WordPressu, pagename a page_id, pomocí kterých se běžně určuje, jaká stránka se má zobrazit.
- Závažnost: CVSS 9.2 (Critical)
- Zveřejnění: 22. září 2026.
- Oprava: WordPress záplatoval tuto chybu až do velmi staré verze 4.7. Opravené jsou tedy i velmi staré větve, což samo o sobě ukazuje, jak vážně chybu vývojáři berou.
Chyba není v šabloně, ale šablona hraje roli. Jednou z podmínek úspěšného zneužití je konkrétní struktura aktivní šablony. Ne každý web s neopraveným WordPressem je proto zranitelný stejně. Bez podrobné analýzy vlastní šablony nemá provozovatel jistotu, zda je jeho web zranitelný. Důrazně proto doporučujeme provést aktualizaci na poslední verzi.
Proč %252e%252e
Path traversal je starý útok: do cesty k souboru se vloží ../ a aplikace se tím dostane o adresář výš, než by měla. Proti tomu existuje řada obecných filtrů, a proto útočníci sekvenci .. maskují kódováním.
Tečka se v URL kóduje jako %2e. Znak procenta se kóduje jako %25. Když se zakóduje už zakódovaná tečka, vznikne %252e:
. → %2e (jednou zakódováno)
%2e → %252e (podruhé zakódováno)
Kdo požadavek dekóduje jen jednou, uvidí %2e%2e, tedy text, ve kterém žádné .. není. Teprve druhé dekódování z něj udělá skutečné ... Útok v této kampani byl postavený právě tak, aby prošel kolem filtrů, které hodnotu rozbalují jen jednou, a na .. se proměnil až uvnitř cílové aplikace.
Jak útok vypadal v datech
Všechna čísla níže pocházejí z logů WEDOS Global Protection, která stojí těsně před webem zákazníka. Jsou to agregované hodnoty od 22. 9. 20:33 do 23. 9. 8:54 (CEST). Jsou to jednoznačně identifikované pokusy o zneužití této zranitelnosti. A kampaň je teprve na začátku.
| Ukazatel | Hodnota |
|---|---|
| Škodlivé požadavky | 3 252 |
| Zasažené weby (domény) | 696 |
| Zdrojové IP adresy | 37 |
| Počet unikátních scannerů | 9 |
| Podíl zásahů na webech s WordPressem | 88 % |
| Metoda | POST 61 %, GET 39 % |
| Průměr na jeden web | přibližně 4,7 pokusu |
Statistiky neobsahují blokované požadavky na L3/L4 ze známých botnetů, kde ještě neznáme přesný cíl útoku.

Časová osa
- 22. září, 20:33: začátek první vlny, v den zveřejnění zranitelnosti.
- 23. září, 0:00–1:00: vrchol první vrlny, zhrube 1 525 požadavků za hodinu.
- 23. září, 5:00–8:54: druhá vlna, po hodinách 34 → 312 → 446 → 366 požadavků.
- 23. září dopoledne: analýza, návrh pravidla, testy a nasazení pravidla na WAF WGP.
Jedna kampaň, ne cílený útok
Poměr zdrojů a cílů je výmluvný: 37 IP adres a 9 TLS otisků proti téměř 700 webům. Jeden TLS otisk (JA4) přitom tvořil 48 % veškerého provozu, tři nejčastější dohromady 74 %. Na jeden web připadalo v průměru necelých pět pokusů.
Takhle vypadá plošný sken. Útočník nemíří na konkrétního zákazníka. Projíždí co nejvíc webů, zkouší signaturu a čeká, kde se to chytne. Na weby s WordPressem připadlo 88 %, zbytek skener zkoušel i na webech bez WordPressu. Cíle si tedy předem příliš netřídil.
Odkud útok přišily první dvě vlny
- Země: Nizozemsko 71,5 %, USA 19,4 %, Singapur 3,5 %, Kambodža 2,1 %, Německo 1,2 %, Turecko 1,0 %.
- Sítě: 62 % provozu přišlo z jediného autonomního systému, další tři AS měly 19 %, 10 % a 4 %.
- Typ sítě: 26 % adres patřilo datacentrům, která naše klasifikace vede jako podezřelá, 3 % běžným datacentrům a 63 % bez zařazení.
- User-Agent: 40 % požadavků se hlásilo jako Chrome, 60 % jako nerozpoznaný klient.
Co jsme udělali
1. Najít útok v provozu
Signatura je dobře definovaná: dvojitě zakódované .. (%252e%252e) v hodnotě parametru pagename nebo page_id. Podle ní jsme v logech dohledali celou kampaň včetně zářijových serverů.
2. Navrhnout úzké pravidlo
Cílem nebylo blokovat „cokoliv podezřelého“, ale přesně tenhle vzor. Pravidlo se aktivuje jen tehdy, když je dvojitě zakódované .. přímo v hodnotě jednoho z těchto dvou parametrů. Stejná sekvence v jiném parametru nebo parametr s podobným jménem pravidlo nespustí.
Pro takto úzké pravidlo jsme se rozhodli ze dvou důvodů:
- Dvojitě zakódované
..v parametrechpagenameapage_idnemá žádné legitimní použití. - Běžný web tam posílá slug stránky nebo číslo.
3. Otestovat, že chytá, co má, a nechytá, co nemá
Pravidlo jsme nejdřív ověřili na živém testovacím prostředí:
- Útočné požadavky včetně variant zápisu, kterými se útočníci snaží podobná pravidla obcházet: všechny zachyceny.
- Legitimní hodnoty jako
?pagename=kontakt,?page_id=1843nebo?pagename=verze-2.0: propuštěny. - Stejný vzor v jiných parametrech a parametry s podobným názvem: propuštěny, protože na ně pravidlo necílí.
Nejdůležitější byl test na skutečném provozu. Z logu za posledních šest hodin jsme vzali 200 reálných legitimních požadavků, které obsahovaly pagename nebo page_id, ale ne útočný vzor, a protáhli je pravidlem:
propuštěno: 200
falešně pozitivních: 0
4. Nasazení
Požadavek s touto signaturou teď dostane okamžitou odpověď 456 a na web zákazníka se vůbec nedostane. Jde o virtuální patch: zákazník nemusí nic nastavovat a ochrana funguje i na webech, které WordPress zatím neaktualizovaly.
Od začátku analýzy po nasazení uplynula necelá hodina. Podle interní komunikace: zhruba 10 minut pochopení útoku a dohledání vzorků v logech, 13 minut návrh pravidla, automatizované testy a ladění pak zabralo několik desítek minut a zhruba 5 minut nasazení a distribuce pravidla po celém světě.
Co to znamená pro provozovatele WordPressu
- Aktualizujte WordPress. Oprava existuje pro všechny verze od 4.7. Pravidlo na straně WGP vám dává čas, ale opravu na webu nenahrazuje.
- Nespoléhejte na šablonu. To, že exploit závisí na struktuře aktivní šablony, neznamená, že je váš web v bezpečí.
- Podívejte se do logů. Pokud provozujete WordPress mimo WGP, hledejte v přístupovém logu požadavky s
%252e%252ev parametrechpagenamenebopage_id. Legitimní provoz nic takového neposílá. - „200“ v logu neznamená kompromitaci, ale ani ji nevylučuje. Při podezření kontrolujte samotný web, ne jen stavové kódy.

