WordPress 的 REST API 是一个强大的功能,它允许开发者通过 HTTP 请求与站点的数据进行交互。然而,默认情况下,WordPress REST API 对外公开了许多端点(Endpoints),这意味着即使是未登录的匿名用户,也可以读取诸如文章、页面、甚至是系统注册用户列表等信息。
暴露用户列表等数据可能会被恶意攻击者用于暴力破解密码或进行垃圾邮件发送(用户名枚举攻击)。因此,出于安全考虑,很多站点都需要限制或完全关闭对 REST API 的匿名访问。本文将为您介绍几种有效的方法。
为什么要限制 REST API 匿名访问?
- 防止用户名枚举: 默认的
/wp-json/wp/v2/users端点会暴露网站的用户名和作者 ID。这是最常见的安全隐患之一。 - 防止内容被恶意抓取: 攻击者可以轻易通过 API 批量获取您的文章内容,甚至是一些未公开的草稿或自定义文章类型。
- 减少服务器资源消耗: 限制不必要的 API 请求可以减轻服务器负载,对于抵御一些轻量级的 CC 攻击也有一定帮助。
- 保护敏感数据: 如果您的站点有自定义的 REST API 端点,可能会无意中泄露非公开的数据记录。
方法一:使用代码要求所有 REST API 必须进行身份验证(推荐)
这是最常见、也最安全的做法。通过使用 rest_authentication_errors 钩子,我们可以拦截所有的 API 请求。如果请求来自未登录的访客,则返回未授权的错误提示。这样,只有登录用户(或提供了有效应用密码等身份验证凭证的请求)才能访问 API。
将以下代码添加到您当前的子主题的 functions.php 文件中:
add_filter( 'rest_authentication_errors', function( $result ) {
// 如果已经有其他身份验证错误状态,则直接返回
if ( true === $result || is_wp_error( $result ) ) {
return $result;
}
// 如果当前用户未登录,则拒绝访问
if ( ! is_user_logged_in() ) {
return new WP_Error(
'rest_not_logged_in',
__( '您当前未登录,禁止访问 REST API。', 'your-text-domain' ),
array( 'status' => 401 )
);
}
return $result;
});
代码原理解析: 当接收到 REST API 请求时,WordPress 会触发该过滤器。代码中检查了 is_user_logged_in()。如果没有登录,就会抛出一个带有 401 Unauthorized 状态码的 WP_Error。由于是在非常早期的阶段就拦截了请求,因此能有效避免后续的数据库查询消耗。
方法二:仅局限于移除敏感端点(如 /users)
完全禁用匿名访问可能会带来副作用。如果您的主题或插件(例如某些启用了 Ajax 提交的表单插件、基于 React/Vue 构建的无头前端等)依赖于公开的 REST API,全局禁用的方法一会导致它们失效。在这种情况下,您可以选择保留大部分 API,而仅仅移除或修改最敏感的 /users 端点。
add_filter( 'rest_endpoints', function( $endpoints ) {
// 移除默认的 users 集合端点和单个 user 端点
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;
});
这段代码通过 rest_endpoints 过滤器,直接从注册的路由列表中注销了获取用户的端点。无论是匿名访客还是已经登录的管理员,都无法再通过该端点获取用户列表。如果您需要自己在后台使用这个端点,可以结合 current_user_can( 'list_users' ) 进行判断后再决定是否 unset。
方法三:使用安全插件实现控制
如果您不想手动修改代码,使用现成的 WordPress 安全插件来限制 REST API 的访问也是一种方便快捷的方法:
- Disable REST API: 这是一款非常轻量级的免费插件,它的专门用途就是限制 REST API。您可以配置是完全禁用匿名访问,还是通过白名单允许特定的端点进行访问(例如允许 Contact Form 7 的端点通过)。
- Wordfence Security / iThemes Security: 如果您已经安装了这些综合性的主流安全插件,它们通常会在设置项中包含类似“关闭 REST API 匿名访问”、“禁用用户枚举(Disable User Enumeration)”的功能。您只需在插件的设置面板中将其开启即可。
总结
在大多数传统的用于展示信息的 WordPress 站点上,限制 REST API 的匿名访问是一个非常值得推荐的安全加固措施。如果您只是一个普通的站长,推荐通过安全插件或者方法一进行全局限制;如果您的站点比较复杂或者前端功能依赖 API,则需要谨慎行事,通过测试后选择方法二对敏感路由进行部分限制过滤。
