Seznam WordPress uživatelů je veřejně dostupný

Co to je

Endpoint /wp-json/wp/v2/users vrací seznam všech autorů webu — včetně user_login. Tedy přesně toho, co potřebujete na přihlašovací obrazovce. Navíc i /?author=1 se přesměruje na URL obsahující jméno autora.

WordPress tohle dělá z designu — REST API má veřejně vystavovat autory, aby šablony věděly, kdo článek napsal. Ale výchozí nastavení ukazuje i username, ne jen jméno.

Proč je to problém

Brute-force útok na WordPress má dvě poloviny: uhádnout username a uhádnout heslo. /wp-json/wp/v2/users uživateli rovnou dá první půlku. Útočník už nehledá admin, root nebo info, ale rovnou cíleně útočí na vaše skutečné účty.

Pokud máte aktivní XML-RPC nebo nemáte rate-limit na /wp-login.php, je tahle dvojice (user enum + brute-force) realistický útok do několika hodin.

Jak to opravit

Krok 1 — zakázat REST API users endpoint

Do functions.php nebo do site-specific pluginu:

add_filter('rest_endpoints', function ($endpoints) {
    if (isset($endpoints['/wp/v2/users'])) {
        unset($endpoints['/wp/v2/users']);
    }
    if (isset($endpoints['/wp/v2/users/(?P<id>[\d]+)'])) {
        unset($endpoints['/wp/v2/users/(?P<id>[\d]+)']);
    }
    return $endpoints;
});

Krok 2 — zablokovat ?author=N redirect

add_action('template_redirect', function () {
    if (isset($_GET['author']) && !current_user_can('edit_posts')) {
        wp_redirect(home_url(), 301);
        exit;
    }
});

Krok 3 — oddělit display name od username

Když už user enum nějak unikne (cache, theme, plugin), nemělo by user_nicename být totožné s user_login. V administraci jednotlivých uživatelů:

Username v WordPressu nelze po vytvoření měnit přes UI. Pokud máte admina jménem admin, vytvořte si nového admina, přiřaďte mu všechny posty a starého admin smažte (WP nabídne „převést příspěvky“ při mazání).

Plugin alternativa

WPS Hide Login + Stop User Enumeration řeší obojí ve dvou kliknutích.

Reference