WordPress 4.7.1 REST API expune în continuare utilizatorii

13 ian. 2017, 02:45:03
Vizualizări: 41.4K
Voturi: 37

Am actualizat WordPress-ul la versiunea 4.7.1 și după aceea am încercat să enumăr utilizatorii prin REST API, care ar fi trebuit să fie rezolvat, dar am putut să recuperez în continuare utilizatorii.

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

Rezultat:

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

Changelog-ul din ultima versiune:

REST API-ul expunea date despre utilizatori pentru toți utilizatorii care au fost autori ai unei postări de tip public. WordPress 4.7.1 limitează acest lucru doar la tipurile de postări care au specificat că ar trebui să fie afișate în REST API. Raportat de Krogsgard și Chris Jean.

După instalarea plugin-ului Disable REST API, pare că totul funcționează bine, dar nu-mi place să folosesc plugin-uri pentru fiecare lucru minor.

Rezultatul după utilizarea plugin-ului este:

{"code":"rest_cannot_access","message":"Doar utilizatorii autentificați pot accesa REST API.","data":{"status":401}}

Cum pot rezolva această problemă fără a folosi plugin-ul, sau de ce există în continuare după actualizare?

EDITARE 30.9.2017

Am realizat că există un conflict între plugin-ul contact 7 și Disable REST API care va genera eroarea 401 unauthorized.

Când încerci să trimiți un mesaj prin formularul contact 7, acesta va face o cerere

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

și dezactivarea acestuia nu este o idee bună.

4
Comentarii

Din câte înțeleg, istoricul modificărilor nu spune că utilizatorii nu mai sunt expuși. Cred că ar trebui interpretat ca „Expunerea este limitată la utilizatorii care au creat tipuri de postări care sunt setate să fie expuse prin REST API.” Deci, de îndată ce un utilizator creează o postare pentru un tip de postare care este expus (spre deosebire de a fi doar public), autorul va fi de asemenea expus.

JHoffmann JHoffmann
13 ian. 2017 10:04:36

Utilizatorii nu sunt considerați date secrete/private în WP, ceea ce ai cerut va strica multe plugin-uri care folosesc REST API, precum și editorul de blocuri. De exemplu, nu va fi posibil să afișezi autorul unei postări sau orice altă informație în afară de ID-ul său

Tom J Nowell Tom J Nowell
5 ian. 2021 12:42:36

Exact. Tocmai am primit un raport Open Bug Bounty despre asta pe site-ul meu WP pe versiunea 5.x. Chiar și script kiddies (https://www.openbugbounty.org/researchers/Cyber_World/) înțeleg greșit CVE-ul pentru aceasta (https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5487). A fost rezolvat pentru cei care sunt îngrijorați. Nu copiați și lipiți toate acestea fără a înțelege ce folosește cu adevărat și dacă aveți nevoie de ele.

Tony-Caffe Tony-Caffe
19 nov. 2021 21:58:33
Toate răspunsurile la întrebare 12
7
30

Acest fragment de cod va ascunde rezultatele pentru endpoint-urile de utilizatori, articole și comentarii și va returna eroarea 404, în timp ce restul apelurilor API vor continua să funcționeze normal.

::ACTUALIZARE::

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;
});

::ACTUALIZARE::

Acest fragment va elimina toate endpoint-urile implicite.

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

27 ian. 2017 20:38:15
Comentarii

conform link-ului menționat, poți filtra și endpoint-urile...

BlueSuiter BlueSuiter
27 ian. 2017 20:46:12

Aceasta este cea mai bună soluție până acum.

mirsad mirsad
30 sept. 2017 05:02:40

Unde se adaugă acest cod personalizat? Nu menționați unde ar trebui salvat acest lucru.

wruckie wruckie
5 dec. 2017 22:31:12

Puteți păstra acest cod în functions.php al temei dumneavoastră.

BlueSuiter BlueSuiter
6 dec. 2017 08:15:47

Această soluție dezactivează toate operațiunile CRUD pe utilizatori, consultați această implementare doar pentru cererile GET: https://github.com/szepeviktor/wordpress-fail2ban/commit/98eb4f292a5a6bdae637f9410eb7bb9d6dffd81c

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

Cum pot dezactiva mydomain.com/wp-json/ pentru a nu mai afișa toate aceste date în format json?

Solomon Closson Solomon Closson
20 sept. 2019 20:27:16

Această soluție este incompatibilă cu Gutenberg, care aruncă:

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 }

Ar fi mai bine să forțăm autentificarea pe aceste endpoint-uri.

drzraf drzraf
13 nov. 2020 20:50:31
Arată celelalte 2 comentarii
0
/**
 * Învelește un callback implicit existent transmis ca parametru și creează
 * un nou callback de permisiune introducând verificări preliminare și
 * revenind la callback-ul implicit în caz de succes.
 */
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',
                __( 'Ne pare rău, nu aveți permisiunea de a accesa utilizatorii.' ),
                [ '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');
  • Endpoint-urile nu sunt blocate pentru administratori (Gutenberg continuă să funcționeze)
  • Endpoint-ul respinge utilizatorii anonimi într-un mod corespunzător.
  • Este suficient de generic pentru a suporta endpoint-uri viitoare.
  • current_user_can ar putea fi îmbunătățit, făcut mai generic.
  • Se presupune că metoda GET este prima pentru o rută înregistrată (ceea ce până acum a fost întotdeauna adevărat)
13 nov. 2020 21:53:00
0

Eliminați link-ul API din head-ul HTML dacă doriți.

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

Apoi solicitați autentificare pentru toate cererile.

// Puteți solicita autentificare pentru toate cererile REST API prin adăugarea unei verificări is_user_logged_in la filtrul 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', 'Doar utilizatorii autentificați pot accesa REST API.', array( 'status' => 401 ) );
    }
    return $result;
});

Aceasta vă va lăsa cu mesajul dorit.

Pentru a opri enumerarea, puteți folosi ceva de genul acesta.

// https://perishablepress.com/stop-user-enumeration-wordpress/
// blochează scanările de enumerare WP
    // https://m0n.co/enum
    if (!is_admin()) {
        // format URL implicit
        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) {
        // format URL permalink
        if (preg_match('/\?author=([0-9]*)(\/*)/i', $request)) die();
        else return $redirect;
    }

Consultați întregul articol pentru alte tehnici avansate.

18 iun. 2017 16:38:22
1

doar un alt răspuns:

add_filter( 'rest_user_query', '__return_null' );
add_filter( 'rest_prepare_user', '__return_null' );
14 iul. 2020 15:58:30
Comentarii

Probabil cea mai curată soluție dintre toate, mulțumesc.

MitchellK MitchellK
2 mai 2021 08:49:16
1

Puteți repara aceasta prin configurarea nginx/apache:

location ~* /wp-json/wp-v2/users {
        allow ip_address;
        deny all;
}
12 dec. 2018 15:37:09
Comentarii

va strica wp-admin (Gutenberg)

ViliusL ViliusL
18 nov. 2021 10:02:57
0

Cod .htaccess pentru a bloca toate scanările autorilor

# Început blocare scanări autori
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} (author=\d+) [NC]
RewriteRule .* - [F]
# Sfârșit blocare scanări autori

Puteți elimina acest cod prin funcție așa cum sugerează răspunsul acceptat

11 dec. 2020 16:24:56
0

Am folosit acest mic cod în fișierul functions.php:

/**
 * Acces API REST doar pentru administratori
 *
 * @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('Ne pare rău, nu aveți permisiunea să accesați aceste date','API REST Interzis',403);
  }
}
add_filter( 'rest_api_init', 'api_rest_only_for_admin_users', 99 );
5 ian. 2021 12:24:30
0

Pentru a completa răspunsul lui BlueSuiter din 2017, iată o soluție pentru a filtra utilizatorii după rol, care face soluția compatibilă cu editorul 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;
    
});

Editorul Gutenberg trebuie să interogheze API-ul REST pentru a obține autorul. Prin urmare, este necesar să permitem accesul pentru toate rolurile de utilizator de pe site-ul tău care au acces la editorul Gutenberg, fără a uita de postările personalizate.

Pe endpoint-ul public al API-ului REST, se va returna o eroare 404 deoarece is_user_logged_in va returna întotdeauna false.

30 nov. 2021 00:02:35
0

Dacă utilizați un firewall pentru a proteja site-ul WordPress, cea mai bună opțiune este să blocați punctul final (endpoint) API care expune detaliile utilizatorilor prin intermediul firewall-ului.

Detectați URL-ul https://example.com/wp-json/wp/v2/users și pur și simplu blocați-l din firewall.

Editare: blocați doar punctul final specific pentru detaliile utilizatorilor și nu întregul API REST.

23 mar. 2021 11:03:25
0
// Bloc API JSON WP pentru utilizatori
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 oct. 2023 11:14:12
1

Am creat un plugin complet care funcționează pentru acest lucru în GITHUB.

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

Ceea ce am făcut a fost să mă asigur că folosesc INIT pentru începutul acțiunii, acest lucru asigură că funcțiile pluggable funcționează conform așteptărilor.

De asemenea, folosesc capacitatea WordPress 'Edit_posts' pentru API. Acest lucru asigură că administratorul și editorul de blocuri funcționează corect.

Aruncă o privire la acel plugin pentru a rezolva orice probleme CVE-2017-5487 ridicate de auditorii de securitate.

De asemenea, folosește PHP CS, astfel încât va funcționa cu o instalare VIP sau cu ceva care necesită implementarea standardelor.

Sper că acest lucru ajută pe cineva. Mi-a luat ceva timp să fac asta să funcționeze corect pe propriile mele site-uri și servere.

3 apr. 2024 07:11:33
Comentarii

Privind pe scurt codul, numele „hardener” este un pic înșelător, deoarece nu întărește endpoint-urile, ci le face să respingă întotdeauna cererile - pur și simplu îl instalezi condiționat. De asemenea, apelezi funcții de activare și dezactivare care nu există. Dar da, se pare că asta ar face treaba.

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

Pentru a putea remedia această problemă, mai întâi trebuie să cunoști sursa ei.

  1. Folosești pluginuri SEO precum: All in one SEO pack sau Yoast? Încearcă să le dezactivezi și verifică din nou.
  2. Folosești pluginul Jetpack? Încearcă să-l dezactivezi și verifică din nou.

Te rog să-mi spui dacă aceste sugestii te-au îndreptat în direcția corectă.

O metodă rapidă de a rezolva această problemă este să blochezi URL-ul menționat mai jos în fișierul tău .htaccess. https://mywebsite.com/wp-json/wp/v2/users

24 iun. 2017 21:30:56
Comentarii

Primele două puncte pe care le menționezi sunt fără sens, dar metoda "murdară" de blocare a accesului este de fapt mai rapidă decât utilizarea WordPress, deoarece blocarea va fi efectuată la nivelul Apache înainte ca WordPress să fie încărcat.

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