如何构建安全的 WordPress 1:防止用户名暴露
今天开始谈谈如何构建安全的 WordPress 站点,废话不多说,直接来。
WordPress 最常见的攻击
开始之前,我们要明确最常见的 WordPress 攻击就是基于密码的攻击,也就是「暴力破解密码尝试」,指攻击者在登录页面上重复输入不同的用户名和密码,尝试破解进入 WordPress 帐户,攻击者会通过工具不停的尝试。
既然最常见的攻击是「暴力破解密码尝试」,那么我们首先就要把管理员的账号和密码设置得足够复杂,不要像我之前介绍的那样,直接用 admin/admin,最好是符合 WordPress 后台密码设置工具中显示强的这种:

并且移除不再使用的管理账号,或者将其降级,防止因为这些账号引起的安全问题,最后防止用户名暴露,这也是今天今天重点讲解的。
我们知道 WordPress 用户名是 user_login
,然后还有个 user_nicename
,类似 WordPress 的文章,这个也可以说是 user 的 slug, 最长 50 个字符。
默认情况下,在用户注册的时候,直接过滤掉 user_login
一些不适合在链接中生成的字符,然后全部转成小写字母生成 user_nicename
。
用户名是怎么暴露的
因为默认情况下 WordPress 用户的 user_nicename
和 user_login
是一样的,这样只要通过下面几个方法猜测到 user_login
,然后就可以暴力破解。
1. 作者的文章列表链接是:https://blog.wpjam.com/author/superdenis/
,其中的 superdenis
是user_nicename
。
2. 在 body 的 class 中,如果当前用户的作者页,也会出现用户的 user_nicename
。
3. 和 comment 的 class 中,如果留言的用户也是当前站点的用户,也会出现用户的 user_nicename
。
4. 在内置的用户接口 https://blog.wpjam.com/wp-json/wp/v2/users/ 其中 slug
就是 user_nicename
。
如何防止用户名暴露
1. 修改 user_nicename。

WordPress 后台没有提供修改的 user_nicename
的地方,不过不用担心,「WPJAM 用户管理插件」已经实现了该功能, Modular 主题也集成了。
2. user_login 不出现在作者的文章列表链接中
如果用户的 user_nicename
和 user_login
是一样的情况下:
作者文章链接使用 author_id
代替 user_nicename
。
add_filter('author_link', function($link, $author_id, $author_nicename){
$author = get_userdata($author_id);
if(sanitize_title($author->user_login) == $author_nicename){
global $wp_rewrite;
$link = $wp_rewrite->get_author_permastruct();
$link = str_replace('%author%', $author_id, $link);
$link = home_url(user_trailingslashit($link));
}
return $link;
}, 10, 3);
原来的作者链接直接设置为 404 页面,防止用户名暴露。
add_action('pre_get_posts', function($wp_query) {
if($wp_query->is_main_query() && $wp_query->is_author()){
if($author_name = $wp_query->get('author_name')){
$author_name = sanitize_title_for_query($author_name);
$author = get_user_by('slug', $author_name);
if($author){
if(sanitize_title($author->user_login) == $author->user_nicename){
$wp_query->set_404();
}
}else{
if(is_numeric($author_name)){
$wp_query->set('author_name', '');
$wp_query->set('author', $author_name);
}
}
}
}
});
3. user_login 不出现在 body_class 中
add_filter('body_class', function($classes){
if(is_author()){
global $wp_query;
$author = $wp_query->get_queried_object();
if(sanitize_title($author->user_login) == $author->user_nicename){
$author_class = 'author-'.sanitize_html_class($author->user_nicename, $author->ID);
$classes = array_diff($classes, [$author_class]);
}
}
return $classes;
});
4. user_login 不出现在 comment_class 中
add_filter('comment_class', function ($classes){
foreach($classes as $key => $class) {
if(strstr($class, 'comment-author-')){
unset($classes[$key]);
}
}
return $classes;
});
5. 移除用户接口里面的登录名 slug:
add_filter('rest_prepare_user', function($response){
unset($response->data['slug']);
return $response;
});
安全是最重要的,防止用户名暴露是 WordPress 最重要的一步,所以一定要重视。
WPJAM 用户管理插件 已经集上面所有的功能和相关代码,直接启用即可,点击查看 WPJAM 用户管理插件的详细介绍,Modular 主题也集成了,我会在介绍 WordPress 安全这系列文章的时候,将这些安全相关代码也整合到 Modular 主题中,争取打造最安全的 WordPress 主题。
专题:WordPress 安全: