# Zárt végpontok

> A teszt két WordPress-végpontot néz: a nyitott xmlrpc.php-t és a névtelenül elérhető felhasználólistát (REST API); ha bármelyik nyitott, le kell zárni.

A WordPress két olyan végpontot is kitehet az internetre, amelyre a legtöbb oldalnak nincs szüksége a látogatók felé: az `xmlrpc.php`-t és a REST API felhasználólistáját. Az előbbi egy régebbi távoli kezelőfelület, az utóbbi a felhasználók nevét és azonosítóját adhatja ki bejelentkezés nélkül. Mindkettő a jelszó-találgató próbálkozások ismert célpontja vagy segédje, ezért kell tudatosan eldönteni, hogy nyitva maradjanak-e.

Ha az oldal nem WordPress, a teszt nem értelmezhető.

## Hogyan mérjük

A teszt a mért oldal hosztjára három egyszerű lekérést küld. Bejelentkezési vagy admin végpontot soha nem kér: ha egy kérés a `wp-admin` vagy a `wp-login.php` felé irányítana át, a teszt nem követi, és a végpontot nem létezőnek veszi.

**1. Felhasználólista.** A REST API gyökerét a kezdőoldal `Link` fejlécéből vagy a `<link rel="https://api.w.org/">` elemből veszi (ha ugyanazon a hoszton van), különben a `/wp-json/` címet. Ehhez fűzi a `wp/v2/users` útvonalat, és megszámolja, hány felhasználót ad vissza a válasz. A nevek nem maradnak meg, csak a darabszám.

- `401`, `403`, `404`, vagy nem követett átirányítás: a lista zárt (0 felhasználó).
- `200` és a válasz JSON-tömb felhasználói objektumokkal (számmal és névvel): a lista nyitott, a találatok száma a felhasználók száma.
- Ha a válasz rövidítve érkezett (64 KB felett), a teszt a felhasználói azonosítók számát becsli; ha nem tudja megállapítani, az eredmény ismeretlen.
- `429`, `5xx` vagy bármilyen egyéb válasz: ismeretlen.

**2. XML-RPC.** A `/xmlrpc.php` címet kéri le (Bedrock-alapú oldalon a `/wp/xmlrpc.php` címet), átirányítás követése nélkül. Nyitottnak számít, ha a válasz `405` vagy `200`, és a szövege tartalmazza az „XML-RPC server accepts POST requests only” mondatot.

| Eredmény | Mikor |
|---|---|
| Megfelelő | Az `xmlrpc.php` zárt, és a felhasználólista is bizonyosan zárt. |
| Hiba (közepes súlyosság) | Az `xmlrpc.php` nyitott, vagy a felhasználólista legalább egy felhasználót ad. A kártya megnevezi, melyik. |
| Nem értelmezhető | Nem WordPress az oldal. Vagy valamelyik lekérés kimaradt (időtúllépés, kérésszám-korlát), és a másik végpont nem nyitott: részleges ellenőrzésre a teszt nem ad megfelelőt. |

**Mit nem tud a teszt.** Nem próbál bejelentkezni, nem küld XML-RPC hívást, és nem néz más REST-végpontokat. A válasz tartalmát a felhasználólistánál is csak megszámolja.

## Mit érdemes tudni a két végpontról

- A **REST API** a WordPress admin felületének egyik alapja, ezért a WordPress dokumentációja szerint nem szabad teljesen letiltani, mert az adminfelület egyes funkciói megállnak. A felhasználók mezői közül a `username` és az `email` csak szerkesztő (`edit`) környezetben érhető el; a névtelen lista viszont a megjelenített nevet (`name`) és az azonosítót (`id`, `slug`) tartalmazhatja. A felhasználólista korlátozása ezért célzott: csak a `/wp/v2/users` végpontot érdemes zárni a nem bejelentkezett látogatóknak.
- Az **`xmlrpc_enabled`** szűrő a WordPress dokumentációja szerint nem kapcsolja ki az XML-RPC-t teljesen, csak a hitelesítést igénylő metódusokat. A hitelesítés nélküli végpontokat (például a pingbackeket) nem érinti. Ezért a szűrő önmagában nem teszi „zárttá” a fájlt: a teszt a fájl válaszát nézi, így a szerver szintű tiltás a megbízható megoldás.

## Hogyan javítsd

1. **Döntsd el, kell-e az XML-RPC.** Ha valamelyik szolgáltatás vagy alkalmazás (a riport szerint például a Jetpack vagy a WordPress mobilalkalmazás) használja, a letiltással az megszakad. Ha nem használod, tiltsd le.
2. **Zárd le az `xmlrpc.php`-t** a szerver szintjén (az alábbi szabályok valamelyikével).
3. **Korlátozd a felhasználólistát**: nem bejelentkezett látogatónak ne adja ki a `/wp/v2/users` végpontot.
4. **Védd a bejelentkezést is.** A WordPress dokumentációja szerint az erős, egyedi jelszó, a kétlépcsős azonosítás az adminisztrátoroknak (a WordPress magja nem tartalmazza, bővítmény vagy külső azonosításszolgáltató kell hozzá), a bejelentkezési próbálkozások korlátozása a szerveren vagy a CDN/WAF szintjén, és a naprakész core, téma és bővítmények a jelszó-találgatás elleni alapvédelem. A dokumentáció külön említi: az XML-RPC-t védd vagy tiltsd le, ha nincs rá szükség.

### nginx

Az nginx a regex helyeket sorrendben nézi, és az elsőt használja, amelyik illeszkedik. Ezért tedd a többi regex `location` elé, a `location ~ \.php` blokk elé is. Ha a PHP-blokk egy `location / { … }` belsejében van, oda, a PHP-blokk elé tedd. Ha egy illeszkedő prefix `location` `^~` jelölésű (például `location ^~ /wp/`), a regexeket az nginx nem nézi: oda is tedd be.

```nginx title="nginx"
location ~* ^/(wp/)?xmlrpc\.php(/|$) {
    deny all;
}
```

### Apache (.htaccess)

A webroot `.htaccess` fájljának elejére, a többi átírási szabály (`RewriteRule`) elé. WordPress alatt a `# BEGIN WordPress` sor fölé tedd, mert azon belüli sorokat a WordPress felülírhatja.

```apache title=".htaccess"
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteRule (^|/)xmlrpc\.php(/|$) - [F,L,NC]
</IfModule>
```

Ha egy almappában saját `.htaccess` van `RewriteEngine` sorral, az nem örökli ezeket a szabályokat, csak ha ott `RewriteOptions Inherit` is szerepel.

### Cloudflare

Security rules, Create rule, Custom rules:

```text title="Cloudflare"
Expression: (starts_with(lower(http.request.uri.path), "/xmlrpc.php") or starts_with(lower(http.request.uri.path), "/wp/xmlrpc.php"))
Action: Block
```

### WordPress

A felhasználólista korlátozása egy must-use bővítménnyel. Új fájlba kerüljön: `wp-content/mu-plugins/hwp-report-wp-endpoints.php` (Bedrockon `web/app/mu-plugins/…`). A kód a `rest_endpoints` szűrőt használja, és csak a nem bejelentkezett látogatóktól veszi el a felhasználói végpontokat.

```php title="PHP"
<?php
add_filter( 'rest_endpoints', function ( $endpoints ) {
    if ( ! is_user_logged_in() ) {
        unset( $endpoints['/wp/v2/users'], $endpoints['/wp/v2/users/(?P<id>[\d]+)'] );
    }
    return $endpoints;
} );
```

Mellékhatás: kijelentkezve az `_embed` paraméterrel lekért bejegyzésekből is kimarad a szerző adata. Ha egy fejléc nélküli (headless) frontend vagy egy téma ezt használja, ott a szerző neve eltűnik.

## Hogyan ellenőrizd

1. Futtasd újra a riportot.
2. Parancssorból ellenőrizd az `xmlrpc.php` válaszát és a felhasználólistát:

```bash title="Terminál"
curl -s -o /dev/null -w '%{http_code}\n' https://pelda.hu/xmlrpc.php
curl -s -o /dev/null -w '%{http_code}\n' https://pelda.hu/wp-json/wp/v2/users
```

Zárt végpontnál a két kérés `403` vagy `404` kódot ad (a teszt a `401`, `403`, `404` kódokat és a nem követett átirányítást tekinti zártnak). Ha a felhasználólistát a fenti kóddal korlátoztad, a második kérés várhatóan hibakódot ad (például `404`). A lényeg, hogy ne kapj vissza felhasználói objektumokat tartalmazó JSON-tömböt.
