首页  >  问答  >  正文

安全禁用 WP REST API

我正在考虑提高我的 Wordpress 网站的安全性,在这样做时发现默认启用了 WP REST API(如果我没记错的话,从 WP 4.4 开始)。

禁用它的安全方法是什么?

这里的“安全”是指它不会导致意外的副作用,例如不会破坏任何其他 WP 核心功能。

一种可能的方法是使用 .htaccess 重写规则,但令人惊讶的是我没有找到任何这样做的“官方”说明。

非常感谢任何帮助或建议:)

更新: 第三方插件不是我正在寻找的解决方案。尽管我知道有很多可以解决该任务的工具,但它们包含许多会减慢网站速度的额外功能。我希望有一个单行解决方案可以解决这个问题,而无需额外的插件开销。

更新 2: 这是Wordpress的官方意见:https://developer.wordpress.org/rest-api/using-the-rest-api/frequently-asked-questions/#can-i-disable-the-rest-api

据此,Wordpress 团队希望未来的 WP 功能依赖于新的 REST API。这意味着没有保证安全的方法来禁用 REST API。

我们只是希望有足够的安全专家来负责 WP 的安全。

更新3:

WordPress API 手册中提供了一种解决方法 - 您可以要求对所有请求进行身份验证

这可确保禁用对网站 REST API 的匿名访问,只有经过身份验证的请求才有效。

P粉463811100P粉463811100306 天前463

全部回复(2)我来回复

  • P粉478445671

    P粉4784456712024-01-11 15:20:53

    接受的答案会禁用未经身份验证的用户的所有 API 调用,但现在很多插件都依赖于此 API 的功能。

    禁用所有调用将导致意外的网站行为,在我使用此代码时也发生过这种情况。

    例如,ContactForm7 使用此 API 将联系信息发送到数据库(我认为)并进行 ReCaptcha 验证。

    我认为最好为未经身份验证的用户禁用某些(默认)端点,如下所示:

    // Disable some endpoints for unauthenticated users
    add_filter( 'rest_endpoints', 'disable_default_endpoints' );
    function disable_default_endpoints( $endpoints ) {
        $endpoints_to_remove = array(
            '/oembed/1.0',
            '/wp/v2',
            '/wp/v2/media',
            '/wp/v2/types',
            '/wp/v2/statuses',
            '/wp/v2/taxonomies',
            '/wp/v2/tags',
            '/wp/v2/users',
            '/wp/v2/comments',
            '/wp/v2/settings',
            '/wp/v2/themes',
            '/wp/v2/blocks',
            '/wp/v2/oembed',
            '/wp/v2/posts',
            '/wp/v2/pages',
            '/wp/v2/block-renderer',
            '/wp/v2/search',
            '/wp/v2/categories'
        );
    
        if ( ! is_user_logged_in() ) {
            foreach ( $endpoints_to_remove as $rem_endpoint ) {
                // $base_endpoint = "/wp/v2/{$rem_endpoint}";
                foreach ( $endpoints as $maybe_endpoint => $object ) {
                    if ( stripos( $maybe_endpoint, $rem_endpoint ) !== false ) {
                        unset( $endpoints[ $maybe_endpoint ] );
                    }
                }
            }
        }
        return $endpoints;
    }

    这样,现在打开的唯一端点是由插件安装的端点。

    有关您网站上活动的端点的完整列表,请参阅https://YOURSITE.com/wp-json/

    您可以根据您的要求随意编辑 $endpoints_to_remove 数组。

    如果您有自定义帖子类型,请确保将它们全部添加到列表中。

    就我而言,我还将默认端点前缀wp-json 更改为 mybrand-api。这应该对发出数千个暴力请求的机器人起到威慑作用。

    这是我所做的:

    // Custom rest api prefix (Make sure to go to Dashboard > Settings > Permalinks and press Save button to flush/rewrite url cache )
    add_filter( 'rest_url_prefix', 'rest_api_url_prefix' );
    function rest_api_url_prefix() {
        return 'mybrand-api';
    }

    回复
    0
  • P粉512363233

    P粉5123632332024-01-11 12:47:36

    根据作者最初的问题,我选择了来自 WordPress 官方建议的选项 2(https://developer.wordpress.org/rest-api/using-the-rest-api/frequently-asked-questions /#can-i-disable-the-rest-api)。因此,只需放入你的functions.php,只让登录的用户使用其余的API(但只需交叉检查原始链接,以防我的代码块过时;)): 更新(2021年10月1日):

    add_filter( 'rest_authentication_errors', function( $result ) {
        // If a previous authentication check was applied,
        // pass that result along without modification.
        if ( true === $result || is_wp_error( $result ) ) {
            return $result;
        }
    
        // No authentication has been performed yet.
        // Return an error if user is not logged in.
        if ( ! is_user_logged_in() ) {
            return new WP_Error(
                'rest_not_logged_in',
                __( 'You are not currently logged in.' ),
                array( 'status' => 401 )
            );
        }
    
        // Our custom authentication check should have no effect
        // on logged-in requests
        return $result;
    });

    回复
    0
  • 取消回复