WordPress 4.7.1 REST API espone ancora gli utenti

13 gen 2017, 02:45:03
Visualizzazioni: 41.4K
Voti: 37

Ho aggiornato WordPress alla versione 4.7.1, e dopo ho provato a enumerare gli utenti attraverso la REST API, che dovrebbe essere stata corretta, ma sono ancora in grado di recuperare gli utenti.

https://mywebsite.com/wp-json/wp/v2/users

Output:

[{"id":1,"name":"admin","url":"","description":"","link":"https:\/\/mywebsite\/author\/admin\/","slug":"admin","avatar_urls":{"24": ...

Changelog dall'ultima versione:

La REST API esponeva i dati utente per tutti gli utenti che avevano creato un post di un tipo di post pubblico. WordPress 4.7.1 limita questo solo ai tipi di post che hanno specificato di dover essere mostrati all'interno della REST API. Segnalato da Krogsgard e Chris Jean.

Dopo aver installato il plugin Disable REST API, sembra che tutto funzioni correttamente, ma non mi piace usare un plugin per ogni piccola cosa.

L'output dopo l'utilizzo del plugin è:

{"code":"rest_cannot_access","message":"Solo gli utenti autenticati possono accedere alla REST API.","data":{"status":401}}

Come posso risolvere questo problema senza utilizzare il plugin, o perché anche dopo l'aggiornamento questo problema persiste?

MODIFICA 30.9.2017

Mi sono reso conto che c'è un conflitto tra il plugin Contact Form 7 e Disable REST API che ti darà un errore 401 non autorizzato.

Quando provi a inviare un messaggio attraverso il modulo di Contact Form 7, farà una richiesta

wp-json/contact-form-7/v1/contact-forms/258/feedback

e disabilitare questo non è una buona idea.

4
Commenti

Per quanto ne so, il changelog non dice che gli utenti non sono più esposti. Penso che dovrebbe essere letto come "L'esposizione è limitata agli utenti che hanno creato tipi di post che sono impostati per essere esposti tramite REST API." Quindi, non appena un utente crea un post per un tipo di post che viene esposto (al contrario di essere semplicemente pubblico), anche l'autore sarà esposto.

JHoffmann JHoffmann
13 gen 2017 10:04:36

Gli utenti non sono considerati dati segreti/privati in WP, ciò che hai richiesto interromperebbe molti plugin che utilizzano la REST API, così come l'editor a blocchi. Ad esempio, non sarebbe possibile visualizzare l'autore di un post o qualsiasi altra informazione oltre al suo ID

Tom J Nowell Tom J Nowell
5 gen 2021 12:42:36

Esatto. Ho appena ricevuto un Open Bug Bounty su questo riguardante il mio sito WP sulla versione 5.x. Anche gli script kiddies (https://www.openbugbounty.org/researchers/Cyber_World/) fraintendono il CVE per questo (https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5487). È stato patchato per chiunque fosse preoccupato. Non copiate e incollate tutto questo senza capire cosa lo sta realmente utilizzando e se ne avete bisogno.

Tony-Caffe Tony-Caffe
19 nov 2021 21:58:33
Tutte le risposte alla domanda 12
7
30

Questo snippet di codice nasconderà i risultati degli endpoint per utenti, articoli e commenti restituendo un errore 404, mentre tutte le altre chiamate API continueranno a funzionare normalmente.

::AGGIORNAMENTO::

add_filter('rest_endpoints', function(){
    $toRemove = ['users', 'posts', 'comments'];
    foreach($toRemove as $val)
    {
        if (isset($endpoints['/wp/v2/'.$val])) {
            unset($endpoints['/wp/v2/'.$val]);
        }

        if(isset($endpoints['/wp/v2/'.$val.'/(?P<id>[\d]+)'])) {
            unset($endpoints['/wp/v2/'.$val.'/(?P<id>[\d]+)']);
        }
    }        
    return $endpoints;
});

::AGGIORNAMENTO::

Questo snippet rimuoverà tutti gli endpoint predefiniti.

<?php remove_action('rest_api_init', 'create_initial_rest_routes', 99); ?>

27 gen 2017 20:38:15
Commenti

come indicato nel link di riferimento puoi anche filtrare gli endpoint...

BlueSuiter BlueSuiter
27 gen 2017 20:46:12

Questa è la soluzione migliore finora.

mirsad mirsad
30 set 2017 05:02:40

Dove va inserito questo codice personalizzato? Non menzioni dove questo deve essere salvato.

wruckie wruckie
5 dic 2017 22:31:12

Puoi mantenere questo nel functions.php del tuo tema.

BlueSuiter BlueSuiter
6 dic 2017 08:15:47

Questa soluzione disabilita tutte le operazioni CRUD sugli utenti, vedi questa implementazione solo per le richieste GET: https://github.com/szepeviktor/wordpress-fail2ban/commit/98eb4f292a5a6bdae637f9410eb7bb9d6dffd81c

Szépe Viktor Szépe Viktor
28 feb 2019 11:25:41

Come disabilitare mydomain.com/wp-json/ dall'output di tutti questi dati json?

Solomon Closson Solomon Closson
20 set 2019 20:27:16

Questa soluzione non è compatibile con Gutenberg che restituisce:

Uncaught (in promise) Response { type: "basic", url: "/wp-json/wp/v2/users/?who=authors&per_page=100&_locale=user", redirected: false, status: 404, ok: false, statusText: "Not Found", headers: Headers, body: ReadableStream, bodyUsed: false }

Sarebbe meglio forzare l'autenticazione su questi endpoint.

drzraf drzraf
13 nov 2020 20:50:31
Mostra i restanti 2 commenti
0
/**
 * Avvolge un callback esistente passato come parametro e crea
 * un nuovo callback di permesso introducendo controlli preliminari
 * e utilizzando il callback di default in caso di successo.
 */
function permission_callback_hardener ($existing_callback) {
    return function ($request) use($existing_callback) {
        if (! current_user_can('list_users')) {
            return new WP_Error(
                'rest_user_cannot_view',
                __( 'Spiacente, non sei autorizzato ad accedere agli utenti.' ),
                [ 'status' => rest_authorization_required_code() ]
            );
        }

        return $existing_callback($request);
    };
}

function api_users_endpoint_force_auth($endpoints)
{
    $users_get_route = &$endpoints['/wp/v2/users'][0];
    $users_get_route['permission_callback'] = permission_callback_hardener($users_get_route['permission_callback']);

    $user_get_route = &$endpoints['/wp/v2/users/(?P<id>[\d]+)'][0];
    $user_get_route['permission_callback'] = permission_callback_hardener($user_get_route['permission_callback']);

    return $endpoints;
}

add_filter('rest_endpoints', 'api_users_endpoint_force_auth');
  • L'endpoint non è bloccato per gli amministratori (Gutenberg continua a funzionare)
  • L'endpoint rifiuta gli utenti anonimi in modo corretto.
  • È abbastanza generico da supportare ulteriori endpoint.
  • Il current_user_can potrebbe essere ulteriormente migliorato, reso più generico.
  • Si assume che il metodo GET sia il primo per una route registrata (finora è sempre stato vero)
13 nov 2020 21:53:00
0

Rimuovi il link API dall'head HTML se lo desideri.

// https://wordpress.stackexchange.com/a/211469/77054
// https://wordpress.stackexchange.com/a/212472
remove_action( 'wp_head', 'rest_output_link_wp_head', 10 );

Quindi richiedi l'autenticazione per tutte le richieste.

// Puoi richiedere l'autenticazione per tutte le richieste REST API aggiungendo un controllo is_user_logged_in al filtro rest_authentication_errors.
add_filter( 'rest_authentication_errors', function( $result ) {
    if ( ! empty( $result ) ) {
        return $result;
    }
    if ( ! is_user_logged_in() ) {
        return new WP_Error( 'rest_not_logged_in', 'Solo gli utenti autenticati possono accedere alla REST API.', array( 'status' => 401 ) );
    }
    return $result;
});

Questo ti lascerà con il messaggio desiderato.

Ora per fermare l'enumerazione potresti usare qualcosa come questo.

// https://perishablepress.com/stop-user-enumeration-wordpress/
// blocca le scansioni di enumerazione WP
    // https://m0n.co/enum
    if (!is_admin()) {
        // formato URL predefinito
        if (preg_match('/author=([0-9]*)/i', $_SERVER['QUERY_STRING'])) die();
        add_filter('redirect_canonical', 'shapeSpace_check_enum', 10, 2);
    }
    function shapeSpace_check_enum($redirect, $request) {
        // formato URL permalink
        if (preg_match('/\?author=([0-9]*)(\/*)/i', $request)) die();
        else return $redirect;
    }

Consulta l'intero post per ulteriori tecniche.

18 giu 2017 16:38:22
1

solo un'altra risposta:

add_filter( 'rest_user_query', '__return_null' );
add_filter( 'rest_prepare_user', '__return_null' );
14 lug 2020 15:58:30
Commenti

Probabilmente la soluzione più pulita tra tutte, grazie.

MitchellK MitchellK
2 mag 2021 08:49:16
1

Puoi risolverlo attraverso la configurazione di nginx/apache:

location ~* /wp-json/wp/v2/users {
        allow indirizzo_ip;
        deny all;
}
12 dic 2018 15:37:09
Commenti

romperà wp-admin (Gutenberg)

ViliusL ViliusL
18 nov 2021 10:02:57
0

Codice .htaccess per bloccare tutti gli scan degli autori

# INIZIO blocco scan autori
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} (author=\d+) [NC]
RewriteRule .* - [F]
# FINE blocco scan autori

Puoi rimuoverlo tramite funzione come suggerito nella risposta accettata

11 dic 2020 16:24:56
0

Ho utilizzato questo piccolo codice in function.php :

/**
 * Accesso all'API REST solo per amministratori
 *
 * @return void
 */
 function api_rest_only_for_admin_users() {
  $current_user = wp_get_current_user();
  if ( in_array('administrator', $current_user->roles ) ) {
    return;
  } else {
    wp_die('Spiacente, non sei autorizzato ad accedere a questi dati','API REST Vietata',403);
  }
}
add_filter( 'rest_api_init', 'api_rest_only_for_admin_users', 99 );
5 gen 2021 12:24:30
0

Per completare la risposta di BlueSuiter del 2017, ecco una soluzione per filtrare gli utenti in base al ruolo che rende la sua soluzione compatibile con l'editor Gutenberg.

add_filter( 'rest_endpoints', function( $endpoints ) {
    
    if(is_user_logged_in()) {

        $user = wp_get_current_user();

        $roles = array('editor', 'administrator', 'author');

        if( array_intersect($roles, $user->roles ) ) return $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;
    
});

L'editor Gutenberg ha bisogno di interrogare l'API REST per ottenere l'autore. È quindi necessario consentire il passaggio almeno a tutti i ruoli utente del tuo sito che hanno accesso a un editor Gutenberg, senza dimenticare i post personalizzati.

Sull'endpoint pubblico dell'API REST, viene restituito un errore 404 perché is_user_logged_in restituirà sempre false.

30 nov 2021 00:02:35
0

Se stai utilizzando un firewall per proteggere il tuo sito WordPress, l'opzione migliore è bloccare l'endpoint API che espone i dettagli degli utenti direttamente dal firewall.

Identifica l'URL https://example.com/wp-json/wp/v2/users e bloccalo semplicemente dal firewall.

Modifica: blocca solo l'endpoint specifico dei dettagli utente e non l'intera API REST.

23 mar 2021 11:03:25
0
// Blocco API JSON per utenti WP
function disable_custom_rest_endpoints( $endpoints ) {
    $routes = array( '/wp/v2/users', '/wp/v2/users/(?P<id>[\d]+)' );

    foreach ( $routes as $route ) {
        if ( empty( $endpoints[ $route ] ) ) {
            continue;
        }

        foreach ( $endpoints[ $route ] as $i => $handlers ) {
            if ( is_array( $handlers ) && isset( $handlers['methods'] ) &&
                'GET' === $handlers['methods'] ) {
                unset( $endpoints[ $route ][ $i ] );
            }
        }
    }

    return $endpoints;
}
add_filter( 'rest_endpoints', 'disable_custom_rest_endpoints' );
24 ott 2023 11:14:12
1

Ho creato un plugin completo che gestisce questo problema e lo ho pubblicato su GITHUB.

https://github.com/MRKWP/mrkwp-rest-permissions/

Ciò che ho fatto è stato assicurarmi di utilizzare INIT per l'avvio dell'azione, questo garantisce che le funzioni pluggabili funzionino come previsto.

Utilizzo inoltre la capacità 'Edit_posts' di WordPress per l'API. Questo assicura che l'amministratore e l'editor a blocchi funzionino correttamente.

Dai un'occhiata a quel plugin per risolvere eventuali problemi CVE-2017-5487 sollevati dagli auditor di sicurezza.

Utilizza anche PHP CS quindi funzionerà con un'installazione VIP o qualsiasi cosa che necessiti di standard implementati.

Spero che questo possa aiutare qualcuno. Mi ci è voluto un bel po' di tempo per farlo funzionare bene sui miei siti e server.

3 apr 2024 07:11:33
Commenti

Leggendo velocemente il codice, il nome "hardener" è un po' fuorviante poiché non rende più sicuri gli endpoint, ma fa sì che rifiutino sempre le richieste - lo installi semplicemente in modo condizionale. Inoltre stai chiamando funzioni di attivazione e disattivazione che non esistono. Ma sì, sembra che questo possa fare il lavoro.

Rup Rup
4 apr 2024 19:36:22
1
-1

Per poter risolvere questo problema, è necessario prima individuare la fonte dell'issue.

  1. Utilizzi plugin SEO come: All in one SEO pack o Yoast? Prova a disabilitarli e verifica nuovamente.
  2. Utilizzi il plugin Jetpack? Prova a disabilitarlo e verifica nuovamente.

Fammi sapere se questi suggerimenti ti hanno indirizzato nella giusta direzione.

Una soluzione rapida (ma non elegante) è bloccare l'URL sottostante nel tuo file .htaccess. https://mywebsite.com/wp-json/wp/v2/users

24 giu 2017 21:30:56
Commenti

I primi due punti che sollevi non hanno senso, ma il metodo "sporco" per bloccare l'accesso è effettivamente più veloce rispetto all'uso di WordPress, poiché verrà bloccato a livello di Apache prima ancora che WordPress venga caricato.

Alexander Holsgrove Alexander Holsgrove
18 feb 2020 12:54:56