我已将WordPress升级到4.7.1,然后尝试通过REST API枚举用户,该API应该是固定的,但我能够检索用户。

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


输出:

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


最新版本的更改日志:


REST API公开了所有创作用户的用户数据公共帖子类型的帖子
。 WordPress 4.7.1将其限制为仅发布类型,该类型已指定应在REST API中显示。
由Krogsgard和Chris Jean报道。


安装插件Disable REST API后,似乎一切正常,但我不喜欢将每个小东西都用于插件。

使用插件后的输出为:

{"code":"rest_cannot_access","message":"Only authenticated users can access the REST API.","data":{"status":401}}


如何在不使用插件的情况下解决此问题,或者为什么甚至在升级此stil后仍然存在?

编辑30.9.2017

我意识到contact 7插件和Disable REST API之间存在冲突,这将给您401 unauthorized错误。

当您尝试通过contact 7表单发送消息时,它将发出请求

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


并禁用它不是一个好主意。

评论

据我了解,变更日志并不表示用户不会再被暴露。我认为应该将其解读为“曝光仅限于已撰写过设置为通过REST API公开的帖子类型的用户。”因此,一旦用户为公开的帖子类型撰写帖子(相对于公开发表),该作者也会被公开。

也许此链接可以为您提供帮助:wordpress.stackexchange.com/questions/228585/…

WP中不将用户视为机密/私有数据,您所要求的将破坏许多使用REST API的插件以及块编辑器。例如。无法显示帖子的作者或ID以外的任何其他信息

#1 楼

使用此代码段将隐藏用户列表并提供404结果,而其余的api调用则保持原样运行。

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


您可以参考有关WP_REST_API的gitHub存储库上的此链接,以获取更多相同的详细信息。

:: UPDATE ::

要删除所有默认的REST API端点,您必须添加以下内容代码:

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

评论


根据引用的链接,您还可以过滤出端点...

– BlueSuiter
17年1月27日在18:46

这是迄今为止最好的解决方案。

– Mirsad
17年9月30日在2:02

该自定义代码在哪里?您没有提及要保存在何处。

–wruckie
17年5月5日在20:31

您可以将其保留在主题的functions.php中。

– BlueSuiter
17年12月6日在6:15

该解决方案禁用了对用户的所有CRUD操作,请仅针对GET请求查看此实现:github.com/szepeviktor/wordpress-fail2ban/commit/…

–SzépeViktor
19-2-28在9:25



#2 楼

如果愿意,可以从HTML头中删除API链接。

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


然后需要对所有请求进行身份验证。

// You can require authentication for all REST API requests by adding an is_user_logged_in check to the rest_authentication_errors filter.
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', 'Only authenticated users can access the REST API.', array( 'status' => 401 ) );
    }
    return $result;
});


这将为您提供所需的消息。

现在要停止枚举,您可以使用类似的方法。

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


查看整篇文章以了解更多技术。

#3 楼

您可以通过nginx / apache配置对其进行修复:

location ~* /wp-json/wp/v2/users {
        allow ip_address;
        deny all;
}


#4 楼

 /**
 * Wrap an existing default callback passed in parameter and create
 * a new permission callback introducing preliminary checks and
 * falling-back on the default callback in case of success.
 */
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',
                __( 'Sorry, you are not allowed to access users.' ),
                [ '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');
 


端点未被管理员阻止(Gutenberg继续工作)
端点拒绝匿名用户
它足够通用,可以支持更多端点。
可以进一步增强current_user_can,使其更通用。
假设GET方法是注册路由的第一个方法(到目前为止一直都是真的)


#5 楼

.htaccess代码以阻止所有作者扫描
# BEGIN block author scans
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} (author=\d+) [NC]
RewriteRule .* - [F]
# END block author scans

您可以按照建议的接受答案的功能将其删除

#6 楼

只是另一个答案:
 add_filter( 'rest_user_query', '__return_null' );
add_filter( 'rest_prepare_user', '__return_null' );
 


#7 楼

我在function.php中使用了以下代码:
 /**
 * API REST access only for administrators
 *
 * @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('Sorry you are not allowed to access this data','API REST Forbidden',403);
  }
}
add_filter( 'rest_api_init', 'api_rest_only_for_admin_users', 99 );
 


#8 楼

要解决此问题,您首先需要知道问题的根源。


您是否使用SEO插件,例如:集成在一个SEO包或Yoast中?尝试禁用此功能并再次检查。
您是否使用Jetpack插件?尝试禁用此功能,然后再次检查。

请告诉我这是否为您指明了正确的方向。

解决此问题的一种肮脏方法是只阻止.htacces中的url。
https://mywebsite.com/wp-json/wp/v2/users

评论


您提出的前两点是胡说八道,但是阻止访问的“肮脏”方法实际上比使用WordPress更快,因为它甚至会在WordPress加载之前在Apache级别被阻止。

–亚历山大·霍尔斯格罗夫(Alexander Holsgrove)
20-2-18在10:54