A WordPress két olyan felületet tart nyitva, amit a látogatók soha nem látnak, a támadó szkriptek viszont elsők között keresnek meg: a REST API-t a /wp-json/ útvonalon és a régi XML-RPC végpontot a gyökérben lévő xmlrpc.php fájlban. A biztonsági ellenőrzőlisták többsége egyetlen mondatot szán rájuk: tiltsd le mindkettőt. Ez a mondat félig igaz, és pont a rossz fele szokott kárt okozni, mert a REST API ma már nem kiegészítő szolgáltatás, hanem a szerkesztő és a rendelésfelvétel működésének alapja.

Ez az írás azt járja körül, mit adnak ki ezek a felületek magukról, mi hasal el a vak tiltástól, és milyen sorrendben érdemes dönteni. A szövegben végig jelölöm, mi hivatalosan igazolt (a WordPress vagy a bővítmény dokumentációjában szerepel), mi saját tapasztalat (ügyfélkiszolgálás közben mért, ismétlődő minta), és mi szakmai feltételezés (logikus következtetés, de nem bizonyított).
Mire való valójában a /wp-json/ és az xmlrpc.php?
Rövid válasz: a REST API a WordPress mai belső kommunikációs csatornája, az XML-RPC pedig a távoli szerkesztés több mint tizenöt éves öröksége. A kettő nem ugyanaz a kockázat, ezért nem is ugyanaz a válasz rájuk.
Hivatalosan igazolt: a REST API a WordPress 4.7 óta alapból része a magnak, és a blokk-szerkesztő (Gutenberg) teljes egészében rajta keresztül dolgozik. Amikor a szerkesztőben gépelsz, a böngésző néhány másodpercenként a /wp-json/wp/v2/posts/ végpontra küld egy kérést, a médiafeltöltés a /wp-json/wp/v2/media címre megy, a blokk-minták, a widgetek, az Állapotdiagnosztika és a bejelentkezett felhasználók számos admin-képernyője szintén innen szedi az adatot. A REST API tehát kifelé is szolgál nyilvános tartalmat, befelé viszont a WordPress saját idegrendszere.
Hivatalosan igazolt: az xmlrpc.php ezzel szemben egy örökölt felület. Arra találták ki, hogy távoli programok (asztali blogszerkesztők, mobilalkalmazások, más blogmotorok) bejelentkezzenek és tartalmat töltsenek fel, illetve hogy a pingback és trackback rendszer működjön. A mai WordPress-magnak semmilyen belső funkciója nem függ tőle. Ami még függhet: a Jetpack kapcsolata, a WordPress mobilalkalmazás önálló (self-hosted) oldalakon, valamint a MainWP, ManageWP, InfiniteWP típusú távoli menedzsment- és mentőrendszerek egy része.
Ez a különbség adja a cikk egész logikáját: az XML-RPC letiltása a legtöbb oldalon veszteség nélküli lépés, a REST API letiltása viszont sosem az.
Milyen adatok szivárognak ki alapból ezeken a végpontokon?
Rövid válasz: elsősorban felhasználónevek és a telepített bővítmények listája, másodsorban a tartalomszerkezet. Ezek önmagukban nem jelszavak, de célzottá teszik a támadást.
Nyisd meg ezeket privát böngészőablakban a saját oldaladon, kijelentkezve, és nézd meg, mit kapsz:
/wp-json/a felület gyökere. Felsorolja az összes regisztrált névteret. Ha ott látod awc/v3,contact-form-7/v1,elementor/v1,wpforms/v1bejegyzéseket, akkor kívülről is látszik a bővítmény-leltárad egy része./wp-json/wp/v2/usersa leggyakrabban emlegetett gond. Hivatalosan igazolt: a WordPress 4.7.1 óta ez csak azokat a felhasználókat listázza, akiknek van publikált tartalmuk egy nyilvános tartalomtípusban. Kiadja a megjelenített nevet és aslugmezőt, ami nagyon sok oldalon szó szerint megegyezik a bejelentkezési névvel./?rest_route=/wp/v2/usersugyanaz az adat, csak a szép webcímek megkerülésével. Ezt szokták kifelejteni, amikor valaki a webszerveren tiltja a/wp-json/útvonalat, és utána azt hiszi, kész van./?author=1nem REST, de ugyanaz a családi hiba: átirányít a szerző archívumára, és a webcímben megmutatja a felhasználó azonosítóját./wp-json/wp/v2/typesés/wp-json/wp/v2/taxonomiesaz egyedi tartalomtípusaidat és taxonómiáidat mutatja, ami közvetve elárulja, milyen rendszer fut az oldalon./xmlrpc.phpböngészőből megnyitva egy rövid mondattal válaszol, ha él. Ez már elég ahhoz, hogy egy szkript tudja: érdemes visszatérnie.
Hivatalosan igazolt: az XML-RPC két metódusa okozta történelmileg a legtöbb bajt. A pingback.ping arra vehető rá, hogy a te szervered küldjön kérést egy általad megadott címre, ami visszaélésre alkalmas, a system.multicall pedig korábban egyetlen kérésben több száz bejelentkezési kísérletet engedett. A WordPress a 4.4-es verzióban korlátozta a multicallon átmenő azonosítási kísérleteket, tehát a régi, tömeges erőltetett jelszókeresés ma már nem működik ugyanúgy. Saját tapasztalat: a naplókban ettől függetlenül ma is folyamatos a xmlrpc.php irányú próbálkozás, és kisebb tárhelyeken ez önmagában is érzékelhető processzor- és PHP-munkás terhelést jelent, függetlenül attól, hogy sikeres-e.
Szakmai feltételezés: a felhasználónév kiszivárgása a valós támadási láncban másodlagos tényező. Egy erős jelszó, a kétlépcsős azonosítás és a bejelentkezés-korlátozás mellett a név ismerete önmagában keveset ér. A név elrejtése ezért inkább a zaj csökkentése, nem a védelem lényege. Ha egy oldalon a felhasználónév elrejtésén dolgozol, de nincs rajta kétlépcsős azonosítás, akkor rossz sorrendben haladsz.
Mi törik el, ha vakon letiltod mind a kettőt?
Rövid válasz: a szerkesztő, a médiafeltöltés, a blokk-alapú kosár és pénztár, több űrlapbővítmény, a Jetpack, a mobilalkalmazás és a külső rendszerek szinkronja. A legveszélyesebb az, ami némán romlik el.
A REST API oldalán a látható hibák jönnek elsőként. Ha a /wp-json/ útvonalat webszerver-szinten zárod le, akkor a bejelentkezett szerkesztőt is elvágod: a blokk-szerkesztő mentéskor a Frissítés sikertelen jellegű hibaüzenetet dobja, a médiafeltöltés elakad, az Állapotdiagnosztika pedig REST API hibát jelez. Ezt legalább észreveszed.
A csendes károk rosszabbak. Hivatalosan igazolt: a WooCommerce blokk-alapú kosara és pénztára a Store API-ra épül, ami a /wp-json/wc/store/v1/ útvonalon él. Ha ezt elzárod, a kosár üresnek látszik vagy a pénztár nem töltődik be, miközben az admin felület tökéletesen működik. Saját tapasztalat: ezt átlagosan nem aznap veszi észre a tulajdonos, hanem akkor, amikor feltűnik, hogy egy hete nem jött rendelés. A régi, rövidkódos kosár és pénztár nem érintett, ezért ugyanaz a beállítás az egyik webshopon ártalmatlan, a másikon bevételkiesés.
Ugyanez igaz az űrlapokra. A Contact Form 7 a saját REST-végpontjára küldi a beküldést, több más űrlapbővítmény pedig részben admin-ajax.php-t, részben REST-et használ. Ha az űrlap beküldés után csak pörög, vagy hibát ír, ott a REST-korlátozás a gyanúsított. Saját tapasztalat: az űrlaphiba a legdrágább típus, mert az érdeklődő nem szól, hogy nem ment át az üzenet, egyszerűen továbbáll.
Az XML-RPC oldalán rövidebb a lista, de nem üres: a Jetpack kapcsolata megszakadhat, a WordPress mobilalkalmazás nem tud bejelentkezni önálló oldalra, és a régebbi távoli mentőrendszerek elveszítik a hozzáférést. A pingback és trackback szintén megszűnik, ami a legtöbb oldalon inkább előny, mint veszteség.
Milyen döntési fa alapján válaszd ki, mit zársz le?
Rövid válasz: előbb mérd meg, mit használ az oldal, aztán az XML-RPC-t zárd le teljesen, a REST API-t viszont csak végpont szinten korlátozd.
- Nézd meg a naplót, ne tippelj. A tárhely hozzáférési naplójában egyetlen sorral megkapod a nagyságrendet:
grep 'xmlrpc.php' access.log | wc -l, majd ugyanezwp-jsonmintával. Ha az XML-RPC forgalom kizárólag ismeretlen külföldi címekről, POST kérésként, hitelesítés nélkül érkezik, akkor senki nem használja jóhiszeműen. - Kérdezd meg magadtól: kell-e az XML-RPC? Aktív a Jetpack? Bejelentkezik-e valaki a WordPress mobilalkalmazással? Fut-e MainWP, ManageWP vagy hasonló távoli menedzsment? Ha mindháromra nem, akkor az
xmlrpc.phplezárható, és ez az egyetlen lépés, amit szerverszinten érdemes megtenni. - Ha mégis kell, korlátozz teljes tiltás helyett. Vedd ki a pingback metódust, tartsd meg a többit. Szakmai feltételezés: a szolgáltatói címtartományra szűkítés is járható, de a külső szolgáltatók IP-tartományai idővel változnak, ezért ez folyamatos karbantartást igényel, és a hiba csak hetekkel később derül ki.
- A REST API-t soha ne kapcsold ki egészében. Helyette három célzott lépés: a felhasználó-végpont elrejtése kijelentkezett kérők elől, a szerző szerinti felsorolás blokkolása, és a kéréssűrűség korlátozása a tűzfalon vagy a szolgáltatói rétegben.
- Ha ennél szigorúbbra van szükség (például zárt, bejelentkezéses portál), akkor sem tiltás kell, hanem engedélyezőlista: kijelentkezett kérőnek csak a valóban szükséges névterek maradnak nyitva (oEmbed, űrlap, webshop), minden más hitelesítést kér.
Mit tiltsd szerverszinten és mit bővítménnyel?
Rövid válasz: szerverszinten csak az xmlrpc.php-t, mert ott nem indul el a PHP. A REST-korlátozás mindig PHP-ben történjen, mert csak ott tudsz különbséget tenni bejelentkezett és külső kérő között.
Az XML-RPC lezárása Apache alatt, a .htaccess elején:
<Files xmlrpc.php> Require all denied </Files>
Nginx alatt a szerverblokkban:
location = /xmlrpc.php { deny all; access_log off; log_not_found off; }
Ha nincs hozzáférésed a szerverbeállításhoz, a PHP-s megoldás a második legjobb: add_filter( 'xmlrpc_enabled', '__return_false' );. Hivatalosan igazolt: ez a szűrő csak a hitelesítést igénylő metódusokat kapcsolja ki, a pingback tehát ettől még elérhető marad. Ezért érdemes mellé tenni a metódus tényleges eltávolítását is: add_filter( 'xmlrpc_methods', function( $m ) { unset( $m['pingback.ping'] ); unset( $m['pingback.extensions.getPingbacks'] ); return $m; } );
A REST felhasználó-végpont elrejtése kijelentkezett kérők elől, feltételesen:
add_filter( 'rest_endpoints', function( $endpoints ) { if ( is_user_logged_in() ) { return $endpoints; } unset( $endpoints['/wp/v2/users'] ); unset( $endpoints['/wp/v2/users/(?P<id>[\d]+)'] ); return $endpoints; } );
És a szerző szerinti felsorolás kizárása:
add_action( 'template_redirect', function() { if ( ! is_admin() && isset( $_GET['author'] ) ) { wp_safe_redirect( home_url(), 301 ); exit; } } );
Saját tapasztalat: ezt a néhány sort ne a sablon functions.php fájljába tedd, hanem külön fájlba a wp-content/mu-plugins/ könyvtárba. Így sablonváltáskor és sablonfrissítéskor is megmarad, és egy fájl törlésével azonnal visszaáll az eredeti állapot, ha hibát keresel.
Bővítménnyel akkor dolgozz, ha nincs, aki a kódot később karbantartsa. A biztonsági bővítmények (Wordfence, Solid Security és társaik) ugyanezt kapcsolókkal kínálják, plusz naplózást és kéréssűrűség-korlátozást adnak. Saját tapasztalat: a gyakorlatban több kárt láttam abból, hogy valaki egy negyven kapcsolós biztonsági bővítményt telepített és találomra bekapcsolgatta a felét, mint abból, hogy tizenöt sor kód került egy mu-plugin fájlba. A kéréssűrűség-korlátozásra viszont a bővítmény vagy a szolgáltatói tűzfal a jobb hely, mert az PHP előtt tud beavatkozni.
Hogyan ellenőrizd, hogy a szerkesztő és a rendelésfelvétel él-e?
Rövid válasz: két körben, kijelentkezve és bejelentkezve, és a webshopnál mindig valódi teszt rendeléssel. A képernyő látványa nem elég bizonyíték.
Kijelentkezve, privát böngészőablakban
/wp-json/adjon vissza JSON választ. Ha itt 403 jön, túllőttél a célon./wp-json/wp/v2/usersadjon 401-es hibát vagy üres listát./?rest_route=/wp/v2/usersugyanazt adja. Ha ez még mindig kilistázza a neveket, a korlátozásod csak a szép webcímes útvonalra vonatkozik./?author=1ne vigyen a szerző archívumára./xmlrpc.phpadjon 403-at, ha lezártad./wp-json/wp/v2/posts?per_page=1továbbra is működjön, ha nyilvános a tartalom, mert erre több beágyazás és külső előnézet épül.
Bejelentkezve, adminként
- Hozz létre egy új bejegyzést, írj bele, mentsd piszkozatként, majd nyomj közzétételt. Ha Frissítés sikertelen hibát kapsz, a REST-korlátozás túl szoros.
- Tölts fel egy képet közvetlenül a blokk-szerkesztőben, ne a médiatárból.
- Nyisd meg az Eszközök menü Állapotdiagnosztika pontját, és nézd meg, hogy a REST API elérhetőségére nem jelez-e hibát.
- Nyisd meg a böngésző fejlesztői eszközeit (F12), a Hálózat fülön szűrj a
wp-jsonszóra, és keress piros 401 vagy 403 sorokat szerkesztés közben.
Webshopon és űrlapokon
- Privát ablakban tegyél terméket a kosárba, nyisd meg a pénztárat, és vidd végig a rendelést utánvéttel vagy a fizetési szolgáltató teszt üzemmódjában.
- Küldj be minden élő űrlapot az oldalon, és ellenőrizd, hogy a levél tényleg megérkezett, nem csak a köszönő üzenet jelent meg.
- Ha van külső szinkron (számlázó, készletkezelő, csomagküldő), indíts el egy manuális szinkront.
- Két nappal később nézd meg a szerver hibanaplóját és a rendelésszámot az előző hét azonos napjaihoz képest. A némán elromló kosár csak így derül ki időben.
Miért okoz a teljes tiltás gyakran több kárt, mint hasznot?
Rövid válasz: mert a nyereség egy nehezen mérhető kockázatcsökkenés, a veszteség viszont konkrét, elmaradt megrendelés és elmaradt érdeklődő.
Ez a saját álláspontom, és vállalom, hogy vitatható. Az érvelés így néz ki. A REST API teljes lezárásával megszüntetsz egy információszivárgást, ami jellemzően felhasználóneveket és bővítménynevek listáját érinti. Ezek az adatok más úton is megszerezhetők: az oldal forráskódjából, a bővítmények saját fájljaiból, a szerző archívumaiból, régebbi indexelt oldalakból. Cserébe elveszítesz olyan funkciókat, amelyek közvetlenül pénzt hoznak, és amelyek hibája nem jelez, csak elmarad.
A célzott korlátozás ugyanazt a szivárgást zárja el, miközben a szerkesztő és a rendelésfelvetel érintetlen marad. Ez nem garantál védettséget semmilyen támadással szemben, és nem helyettesíti a frissítéseket, az erős jelszavakat, a kétlépcsős azonosítást és a működő mentést. Jó eséllyel viszont javítja az arányt aközött, amit nyersz, és amit kockáztatsz.
Az XML-RPC esetében fordított a mérleg. Ott a mai WordPress-nek nincs belső függősége, a felület viszont folyamatos, automatizált zajt vonz. Ha az adott oldalon senki nem használja, a lezárása tiszta nyereség. A hangsúly az ha szón van, és ezért kezdődik a döntési fa méréssel, nem kapcsolóval.
Források és további olvasnivalók
- WordPress Developer Resources: REST API Handbook
- WordPress Developer Resources: Plugin Handbook, Must Use Plugins
- WordPress Support: XML-RPC és a pingback működése
- WordPress Core Handbook: Application Passwords
- WooCommerce Developer Documentation: Store API
- OWASP: Web Security Testing Guide, Information Disclosure fejezet
- Apache HTTP Server Documentation: Access Control
- Nginx Documentation: ngx_http_access_module
- A REST API-t szerverszinten blokkolni hiba: a bejelentkezett szerkesztőt is elvágja, ezért PHP-szűrővel, feltételesen korlátozz.
- A felhasználónevek a /wp-json/wp/v2/users és a /?rest_route=/wp/v2/users címen is kiszivárognak, a második blokkolását szinte mindenki kifelejti.
- Az xmlrpc.php-t a legtöbb oldalon nyugodtan lezárhatod webszerver-szinten, kivéve ha Jetpack, mobilalkalmazás vagy MainWP jellegű menedzsment fut rajta.
- A letiltás után kötelező végigmenni a szerkesztőn, a médiafeltöltésen, az űrlapokon és egy teszt rendelésen, mert a kosár némán is elromolhat.
- A felhasználónév elrejtése önmagában nem véd: a kétlépcsős azonosítás és a bejelentkezés-korlátozás nagyobb súlyú védelem.
Gyakori kérdések
Le lehet tiltani a WordPress REST API-t teljesen, ha nincs webshopom?
Technikailag igen, de akkor is elromlik a blokk-szerkesztő, a médiafeltöltés és több űrlapbővítmény, mert ezek a bejelentkezett munkamenetben is REST-en dolgoznak. Ha kifejezetten zárt oldalt akarsz, a helyes megoldás a kijelentkezett kérők korlátozása PHP-szűrővel, nem az útvonal blokkolása a webszerveren.
Honnan tudom, hogy szükség van-e nálam az xmlrpc.php fájlra?
Három dolgot nézz meg: fut-e Jetpack, jelentkezik-e be valaki a WordPress mobilalkalmazással, és van-e távoli menedzsment vagy mentőrendszer (MainWP, ManageWP, InfiniteWP) az oldalon. Ha mindháromra nem a válasz, a szerver hozzáférési naplójában pedig csak ismeretlen POST kérések látszanak, akkor nyugodtan lezárhatod.
Mit tegyek, ha a /wp-json/wp/v2/users blokkolása után is látszanak a felhasználónevek?
Szinte biztosan a szép webcímek megkerülésével kérik le őket. Ellenőrizd a /?rest_route=/wp/v2/users címet, és a szerző szerinti felsorolást is (/?author=1). Ha az első még mindig listáz, akkor a korlátozásod webszerver-szintű útvonalszűrés, nem pedig a rest_endpoints szűrőn keresztüli, feltételes megoldás.
Elromolhat a WooCommerce kosár a REST-korlátozástól úgy, hogy nem veszem észre?
Igen, és ez a leggyakoribb csendes hiba. A blokk-alapú kosár és pénztár a Store API-ra épül a /wp-json/wc/store/v1/ útvonalon, az admin felület viszont ettől függetlenül tökéletesen működik. Ezért kell minden ilyen beállítás után privát ablakban végigvinni egy teszt rendelést, és két nappal később összevetni a rendelésszámot az előző hét azonos napjaival.
A felhasználónév elrejtése mennyit ér valójában a biztonság szempontjából?
Csökkenti az automatizált zajt, de önmagában nem véd. A jelszó erőssége, a kétlépcsős azonosítás, a bejelentkezési kísérletek korlátozása és a rendszeres frissítés nagyobb súlyú tényező. Ha a felhasználónév elrejtésén dolgozol, de ezek közül bármelyik hiányzik, érdemes előbb azokkal foglalkozni.
Bővítménnyel vagy kóddal érdemes megcsinálni ezeket a korlátozásokat?
Ha van, aki később karbantartja a kódot, akkor néhány sor egy mu-plugin fájlban átláthatóbb és könnyebben visszavonható. Ha nincs, akkor a biztonsági bővítmény jobb választás, mert naplózást is ad. A kéréssűrűség korlátozására viszont mindenképp a bővítmény vagy a szolgáltatói tűzfal a megfelelő hely.
Források és további olvasnivalók
Ezen az oldalon a hivatalosan igazolt információt elsődleges forrásokból építjük fel; a saját tapasztalatot és a szakmai becslést mindig külön jelöljük a szövegben.