WordPress 4.7.1 REST API仍在向用户公开

时间:2017-01-13 作者:mirsad

我已将WordPress升级到4.7.1, 之后,我尝试通过REST 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中显示的post类型。Krogsgard和Chris Jean报道。

安装插件后Disable REST API, 看起来一切都很好,但我不喜欢把插件用在每一件小事上。

使用插件后的输出为:

{"code":"rest_cannot_access","message":"Only authenticated users can access the REST API.","data":{"status":401}}
我如何在不使用插件的情况下修复此问题,或者为什么即使在升级此stil后仍然存在?

EDIT 30.9.2017

我意识到contact 7 插件和Disable REST API 这会给你401 unauthorized 错误

当您尝试通过contact 7 窗体,它将发出请求

wp-json/contact-form-7/v1/contact-forms/258/feedback
禁用这不是一个好主意。

10 个回复
最合适的回答,由SO网友:BlueSuiter 整理而成

此代码段将隐藏用户、帖子和注释端点结果,并给出404作为结果,而其余API调用将保持原样运行。

::UPDATE::

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

::UPDATE::

此代码段将删除所有默认端点。

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

SO网友:drzraf

/**
 * 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 方法是注册路由的第一个方法(到目前为止一直是正确的)
  • SO网友:lowtechsun

    如果愿意,请从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;
        }
    
    查看整个帖子,了解更多技巧。

    SO网友:vim

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

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

    SO网友:Time Killer

    just another answer:

    add_filter( \'rest_user_query\', \'__return_null\' );
    add_filter( \'rest_prepare_user\', \'__return_null\' );
    
    SO网友:Vasim Shaikh

    .htaccess代码阻止所有作者扫描

    # BEGIN block author scans
    RewriteEngine On
    RewriteBase /
    RewriteCond %{QUERY_STRING} (author=\\d+) [NC]
    RewriteRule .* - [F]
    # END block author scans
    
    您可以按照公认的答案建议按功能删除它

    SO网友:Mickael Bertainchant

    我在函数中使用了这个小代码。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 );
    

    SO网友:Nikhil

    如果您使用防火墙来保护wordpress网站,那么最好的选择是阻止api端点从防火墙中暴露用户详细信息。

    检测urlhttps://example.com/wp-json/wp/v2/users 并简单地从防火墙阻止它。

    编辑:仅阻止特定于用户详细信息的端点,而不是整个REST api。

    SO网友:Afterglow

    为了完成2017年BlueSuiter的回答,这里有一个按角色筛选用户的解决方案,使其解决方案与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;
        
    });
    
    Gutenberg编辑器需要查询REST API以获取作者。因此,有必要让您的站点中至少所有有权访问古腾堡编辑器的用户角色通过,不要忘记自定义帖子。

    在公共REST API端点上,返回404错误,因为is\\u user\\u logged\\u总是返回false。

    SO网友:Foo

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

    您使用的SEO插件是:All-in-one SEO pack还是Yoast?尝试禁用此选项,然后再次检查

    解决这一问题的一个糟糕的方法是,只需在中阻止下面的url。htacces。https://mywebsite.com/wp-json/wp/v2/users

    相关推荐

    wordpress admin security

    我用不同的工具扫描我的网站,但它没有显示恶意脚本。但当我在管理仪表板中看到时,我在body标签下面看到了奇怪的方形符号。我试图检查管理索引文件,根索引文件,但什么都没有。有人放了这个脚本。而且,当我试图采取备份它不允许我采取。使用BackupFordPress插件。然而,所有其他的事情都在运行,但在管理方面仍然存在一些问题。如何检测和删除此项。