昨晚在研究评论结构时,网站右键查看源代码,无意间发现自己的管理员用户名被暴露了...
图 1 评论中暴露登录用户名
如上图,在博主的评论的 class 里看到的 test10 是我本地的测试网站的管理员的用户名!另附搭建本地测试环境的方法:
将 WordPress 作者存档链接中的用户名改为昵称或 ID(修复中文昵称 404)
网站已经使用了上面这篇文章里的隐藏存档链接中管理员用户名的方法,没想到管理员用户名还是以另一种方式暴露了... 不过还好,非常隐蔽~~然后查看了下其它一些知名度高的 wordpress 的博客,他们也全部中招了(话说,各位博主的管理员登录用户名真的好复杂啊!)!看来是 wordpress 的通病了!大家赶紧自查下哦~
本站Dragon 主题已经自带集成了此功能,很好的保障站点的安全。
修复方法
方法 1:直接修改 wordpress 程序
① 然后,查了下代码,查到了这个函数comment_class()
,进一步发现是被这个函数get_comment_class()
(大约在 wp-includes\comment-template.php 的 419 行)暴露管理员的登录用户名... 该函数内容如下:
function get_comment_class( $class = '', $comment_id = null, $post_id = null ) {
global $comment_alt, $comment_depth, $comment_thread_alt;
$comment = get_comment($comment_id);
$classes = array();
// Get the comment type (comment, trackback),
$classes[] = ( empty( $comment->comment_type ) ) ? 'comment' : $comment->comment_type;
// Add classes for comment authors that are registered users.
if ( $comment->user_id > 0 && $user = get_userdata( $comment->user_id ) ) {
$classes[] = 'byuser';
$classes[] = 'comment-author-' . sanitize_html_class( $user->user_nicename, $comment->user_id );
// For comment authors who are the author of the post
if ( $post = get_post($post_id) ) {
if ( $comment->user_id === $post->post_author ) {
$classes[] = 'bypostauthor';
}
}
}
if ( empty($comment_alt) )
$comment_alt = 0;
我们的管理员用户名正是被其中的第 14 行暴露的... 在此,我们只需将这一行中的$user->user_nicename
改为$user->user_id
即可安全的隐藏管理员的登录名了~ 也隐藏了注册用户的登录用户名了!取而代之显示的是注册用户(包括管理员)的 ID。从此再也不用担心网页中会暴露诸位站长的登录用户名了~
② 11 月 02 日经过友链龙砚庭博主的提醒,发现用户页面也有博主登录用户名,如下图:
图 2 用户页面中也暴露登录用户名
然后查到了这个函数body_class()
,进一步发现是被这个函数get_body_class()
(大约在 wp-includes\post-template.php 的 634 行)暴露管理员的登录用户名... 该函数部分内容如下:
elseif ( is_author() ) {
$author = $wp_query->get_queried_object();
$classes[] = 'author';
if ( isset( $author->user_nicename ) ) {
$classes[] = 'author-' . sanitize_html_class( $author->user_nicename, $author->ID );
$classes[] = 'author-' . $author->ID;
}
}
其中该函数的第 5 行也暴露了博主的登录名,将这一行删掉或注释掉即可成功解决~
当然,利用好body_class()
这个函数,也可以得到一些很好的效果:
WordPress 实现中英文数字之间自动加空格排版
友情提示:此方法是直接修改的 wordpress 的源程序,所以每次更新 wordpress 程序都得进行这样的修改。
希望高手能提供更好的方法!
方法 2:过滤掉 "comment-author-" 和 "author-"
11 月 04 日经过张戈的提醒和龙砚庭博主文章的提示,得到了一个基本完美的解决方案:也就是将comment_class()
函数里输出的 comment-author-test10 这个 class 去掉,也将body_class()
函数里输出的 author-test10 这个类似的 class 去掉。因为这个是通过 functions.php 来解决的,所以不用担心 wordpress 程序升级的问题。方法是,将以下代码加入 functions.php 中,即可完事!
/**
*(全网独家)如何正确的避免你的 WordPress 管理员登录用户名被暴露 - 龙笑天下
* https://www.ilxtx.com/further-hide-your-wordpress-admin-username.html
* 说明:直接去掉函数 comment_class() 和 body_class() 中输出的 "comment-author-" 和 "author-"
*/
function lxtx_remove_comment_body_author_class($content){
$pattern = "/(.*?)([^>]*)author-([^>]*)(.*?)/i";
$replacement = '$1$4';
$content = preg_replace($pattern, $replacement, $content);
return $content;
}
add_filter('comment_class', 'lxtx_remove_comment_body_author_class');
add_filter('body_class', 'lxtx_remove_comment_body_author_class');
comment_class()
和body_class()
过滤的结果分别是:
// comment_class()过滤后的结果如下,去掉了原有 class 里的 comment-author-test10,请和上面的图 1 比较
class="comment byuser bypostauthor odd alt thread-odd thread-alt depth-1"
// body_class()过滤后的结果如下,去掉了原有 class 里的 author-test10 和 author-1,请和上面的图 2 比较
class="archive author logged-in"
20161122:才发现其实老外早在 2010 年就发现了这个漏洞...
/**
*(全网独家)如何正确的避免你的 WordPress 管理员登录用户名被暴露 - 龙笑天下
* https://www.ilxtx.com/further-hide-your-wordpress-admin-username.html
* 说明:直接去掉函数 comment_class() 和 body_class() 中输出的 "comment-author-" 和 "author-"
*/
function lxtx_remove_comment_body_author_class( $classes ) {
foreach( $classes as $key => $class ) {
if(strstr($class, "comment-author-")||strstr($class, "author-")) {
unset( $classes[$key] );
}
}
return $classes;
}
add_filter( 'comment_class' , 'lxtx_remove_comment_body_author_class' );
add_filter('body_class', 'lxtx_remove_comment_body_author_class');
代码改自:《Small Security Hole in WordPress Comments》
PS:方法 2 的两段代码二选一哈~ 效果一样!
方法 3:改为输出用户 ID 或用户昵称
11 月 18 日发现inlojv的这个方法也不错,但在改为输出昵称的时候有点错误,对此,我已经优化好了,请放心使用:
/**
*(全网独家)如何正确的避免你的 WordPress 管理员登录用户名被暴露 - 龙笑天下
* https://www.ilxtx.com/further-hide-your-wordpress-admin-username.html
* 说明:comment_class() 和 body_class() 中输出的 nicename 改为 userid 或者 username
* 20170527:优化原 Injov 版的输出昵称方法
*/
function lxtx_change_comment_or_body_classes($classes, $comment_id){
global $wp_query;
$comment = get_comment( $comment_id );
$user = get_userdata( $comment->user_id );
$comment_author = 'comment-author-' . sanitize_html_class( $user->user_nicename, $comment->user_id );
$author = $wp_query->get_queried_object();
$archive_author = 'author-' . sanitize_html_class( $author->user_nicename, $author->ID );
foreach( $classes as $key => $class ) {
switch( $class ) {
case $comment_author:
// $classes[$key] = 'comment-author-' . sanitize_html_class( $comment->comment_author, $comment->user_id );
$classes[$key] = 'comment-author-' . sanitize_html_class( $comment->user_id );
break;
case $archive_author:
// $classes[$key] = 'author-' . sanitize_html_class( get_the_author_meta( 'display_name' ), $author->ID );
$classes[$key] = 'author-' . sanitize_html_class( $author->ID );
break;
}
}
return $classes;
}
add_filter( 'comment_class', 'lxtx_change_comment_or_body_classes', 10, 2 );
add_filter( 'body_class', 'lxtx_change_comment_or_body_classes', 10, 2 );
注:注释的两行代码为替换成昵称,不了解可以不理会~~
我现在的策略是,非管理员显示的是用户的 ID,管理员的话,则显示的是......千万不要去查看哦~我现在采用的是方法 2,直接过滤掉了~
延深阅读
我们在上面看到了这个关键字user_nicename
,然而通过百度搜索,找到的准确的相关信息聊聊无几... 还是通过科学上网用谷歌搜索是找到了相关的文章:《users - user_login vs. user_nicename - WordPress Development Stack Exchange》。内容如下图:
图 3 user_login 与 user_nicename 的区别
(英语蹩脚,请见谅~)大意是说,user_login 是登录名,用来登录的;user_nicename 是在作者存档链接中显示的名称。通常,如果你的登录名中没有特殊的字符,则 user_nicename 和 user_login 登录名是一样的;但,如果你是使用电子邮箱注册的 wordpress,也就是说你的登录名是邮箱地址的话,则 user_nicename 和 user_login 是不同的!
比如,如果你的 user_login 登录名是 user@example.com,那么你的 user_nicename 则是 userexample-com。
其他注意
Wordpress 的 rest api 里也会暴露,详情见下文:
如何正确的避免你的 WordPress 管理员登录用户名被暴露【续】
还没有人赞赏,快来当第一个赞赏的人吧!
声明:本文为原创文章,版权归龙笑天下所有,欢迎分享本文,转载请保留出处!