2026 维护说明: 本文现在是一份评论者链接安全指南。文末保留 2011 年原文供溯源;其中的开放重定向、来源页判断、字符串替换和核心文件修改均不应执行。
Table of Contents
先给结论
大多数站点不需要为评论者网址建立跳转页。让 WordPress 直接输出经过清理和转义、且已由管理员审核的评论者网址,并默认在当前标签页打开,通常最简单也最安全。
不要把用户提交的 URL 放进 ?r= 或 ?to= 后再由本站跳转。这样的公共端点会把你的域名变成钓鱼和垃圾信息的跳板;检查 HTTP_REFERER 也不能修复它,因为来源信息可能缺失、被隐私工具裁剪或被伪造。esc_url() 适合输出转义,但并不会把任意外部目的地变成可信地址;`wp_safe_redirect()` 的设计目标则是安全的本地重定向,不是放行用户控制的站外 URL。
选择与边界
| 需求 | 推荐做法 | 不应采用 |
|---|---|---|
| 显示评论者网站 | 使用 WordPress 核心生成的直接链接,并审核评论者 URL | 公共开放重定向端点 |
| 降低评论垃圾与链接操纵 | 开启审核、限制链接数量并使用 ugc;按站点政策增加 nofollow |
用站内跳转伪装外链或相信“权重不会流失” |
| 在新标签页打开 | 仅在确有用户需求时,用受支持的过滤器修改生成后的 <a> 元素并提前告知 |
编辑核心文件或对 HTML 做 str_replace() |
| 处理评论正文里的链接 | 使用 WordPress 自带过滤、允许的 HTML 和审核流程 | 对整个 comment_text 全局替换 href |
评论者网址是公开字段;评论邮箱、IP 地址、审核令牌以及含追踪参数的后台链接不是。不要把这些值写入公开 URL、前端 HTML、截图或诊断日志。若站点涉及未成年人、受监管社区或企业留存要求,应先确定隐私与合规边界。
安全基线:直接、经过审核的链接
- 在预发布环境做完整备份,并记录当前主题、评论插件、缓存/CDN 和评论页面 HTML。搜索旧的
?r=、?to=端点、HTTP_REFERER判断、comment_text字符串替换以及对wp-includes的修改。 - 更新 WordPress、主题和评论插件。恢复所有核心文件修改;`wp core verify-checksums` 可辅助发现核心文件差异,但不能替代备份或人工审查。
- 在“设置 → 讨论”和评论管理页启用符合社区风险的审核。对可疑、拼写混淆、短链、凭据化或带不必要追踪参数的评论者 URL,不要点击;清空或拒绝该 URL/评论。
- 让主题调用 WordPress 的评论作者 API。当前核心的 `get_comment_author_link()` 会对 URL 做输出转义,并构造评论者链接的
rel;不要在模板里重新拼接未转义的comment_author_url。 - 先在预发布环境停用旧跳转逻辑并检查访问日志中的依赖,再做一个有界改动上线。不要把旧端点继续保留为任意目的地跳转;如已有外部依赖,先由安全负责人制定固定目标迁移或明确的退役响应。
WordPress 的评论文档、讨论设置和评论审核指南是处理公开字段、审核队列和链接阈值的起点。审核减少风险,但不能证明目标站点永久安全。
rel:表达链接关系,而不是 SEO 魔术
WordPress 6.2 及以上提供 `comment_author_link_rel` 来过滤评论者链接的 rel 词元。当前核心会为用户生成内容加入 ugc,并根据链接是否站外构造相应关系。Google 也建议给评论或论坛里的用户链接使用 `rel=”ugc”`;在需要与目标保持距离时可同时使用 nofollow。
通常无需添加代码。如果站点政策明确要求所有评论者链接同时带 ugc nofollow,可在小型、可停用的站点插件中使用以下 WordPress 6.2+ 过滤器,而不是修改核心文件:
add_filter(
'comment_author_link_rel',
static function ( array $rel_parts ): array {
$rel_parts[] = 'ugc';
$rel_parts[] = 'nofollow';
return array_values( array_unique( $rel_parts ) );
},
10,
1
);
先确认实际 WordPress 版本和其他插件的过滤结果。nofollow/ugc 是关系提示,不是反垃圾、隐私隔离或访问控制;把链接藏在本站重定向后面、再用 robots.txt 禁止抓取,也不会把开放重定向变安全,更不能保证搜索排名或“保留权重”。参见 Google 的垃圾政策。
新标签页是可选项,并需提前告知
默认留在当前标签页让浏览器返回键自然工作,通常更可预测。若研究和用户反馈确实支持新标签页,WCAG 技术 G201要求在打开新窗口前提供提示。下面示例仅适用于 WordPress 6.2+,使用 `WP_HTML_Tag_Processor` 修改属性,保留核心已有的 rel,并提供可见和可访问名称提示:
add_filter(
'get_comment_author_link',
static function ( string $link, string $author ): string {
if ( ! class_exists( 'WP_HTML_Tag_Processor' ) ) {
return $link;
}
$tags = new WP_HTML_Tag_Processor( $link );
if ( ! $tags->next_tag( 'a' ) ) {
return $link;
}
$rel_parts = preg_split(
'/[[:space:]]+/',
trim( (string) $tags->get_attribute( 'rel' ) )
);
$rel_parts = is_array( $rel_parts ) ? $rel_parts : array();
$rel_parts = array_values(
array_unique(
array_filter(
array_merge( $rel_parts, array( 'noopener', 'noreferrer' ) )
)
)
);
$notice = __( 'opens in a new tab', 'site-comment-links' );
$tags->set_attribute( 'target', '_blank' );
$tags->set_attribute( 'rel', implode( ' ', $rel_parts ) );
$tags->set_attribute(
'aria-label',
sprintf(
/* translators: %s: comment author name. */
__( '%s (opens in a new tab)', 'site-comment-links' ),
wp_strip_all_tags( $author )
)
);
return sprintf(
'%1$s <span class="comment-link-new-tab-notice" aria-hidden="true">(%2$s)</span>',
$tags->get_updated_html(),
esc_html( $notice )
);
},
20,
2
);
把两个英文字符串加入该站点插件的翻译目录。noreferrer 会减少向目标站点披露来源页,但也会改变分析数据;上线前由隐私和分析负责人确认。若必须兼容 WordPress 6.1 或更早版本,优先升级,不要退回到字符串替换。
为什么旧技巧不安全
- 用户控制的跳转目标: 本站域名会为任意目的地背书,容易被用于钓鱼、垃圾邮件和绕过链接检查。只做语法清理不是目标授权;若业务真的需要跳转,只允许服务端固定映射的少量已审核目标,并由安全团队设计。
- 来源页门禁:
HTTP_REFERER不是身份验证或授权信号。它可能没有、可能泄露敏感路径,也可能被伪造,因此既会误拒绝正常访客,也挡不住攻击者。 str_replace()处理 HTML: 它不了解标签边界,可能改写评论正文、站内链接、单引号/双引号、已编码属性或非链接文本,并产生重复或破损属性。使用指定钩子和 HTML 解析器。- 修改 WordPress 核心: 升级会覆盖改动,也让补丁审计和故障回滚更困难。WordPress 的插件基础文档明确把钩子作为扩展路径。
- “链接权重”神话: 重定向不会自动消除目的地关系,
robots.txt也不是安全边界。应把精力放在真实审核、垃圾评论控制和对用户生成链接的准确标记上。
验证、发布与回滚
在预发布环境至少检查:已批准、待审、垃圾和已删除评论;空 URL、站内 URL、正常 HTTPS URL、IDN/同形异义域名、短链、含查询参数的 URL 和被拒绝协议;登录/退出状态;桌面/移动主题;键盘、屏幕阅读器和焦点行为;缓存/CDN;feed、REST API 与后台页面。浏览器开发工具中应看到直接、正确转义的 href,预期的 rel,且默认没有重定向查询参数。
一次只发布一个变化并保留部署记录。监控 4xx、跳转端点访问、审核队列和用户反馈;日志只保留必要字段,并在共享前删除完整查询串、邮箱、IP、令牌和评论者个人信息。若出现循环跳转、目的地被改写、插件冲突、可访问性退化,或旧端点仍能跳到任意外站,立即停用站点插件/恢复上一版,清缓存并请 WordPress 或安全负责人调查。
官方资料
- WordPress:输出转义
- WordPress:`get_comment_author_link` 过滤器
- WordPress:`comment_author_link_rel` 过滤器
- WordPress:`WP_HTML_Tag_Processor`
- WordPress:评论审核与了解评论垃圾
- Google Search Central:标记外部链接
- W3C WAI:在打开新窗口前提供警告
历史原文存档(请勿执行)
以下是 2011 年源导出的完整可见正文,仅做行尾空白规范化。原文中的两个可用目标已做窄范围替换:站点 URL 替换为
[REDACTED: historical site URL],开放重定向 URL 替换为[REDACTED: historical open-redirect URL]。为让完整正文在本站 Markdown 引擎中保持一个惰性代码围栏,原文中的两个内层三反引号标记各插入了一个零宽断字符,显示文本不变;除此之外未改写正文。代码包含开放重定向、未经授权的外部跳转、脆弱的来源页判断和核心文件修改,请勿复制、运行或部署。
```
WordPress评论者链接重定向跳转并在新窗口中打开
```
**一:评论者链接重定向:**
细心的朋友可能会注意到,在一些[wordpress博客]([REDACTED: historical site URL])上,当随便打开一篇文章,鼠标放在任意一个评
论者上,浏览器状态栏显示的地址为:[[REDACTED: historical open-redirect URL]]([REDACTED: historical open-redirect URL])的形式,打开以后仍是转到评论者的网站上。再观察你的站上面的评论链接,评论者链接直接就显示为评论者的链接。结果都一样,
有什么区别呢?从一定程度上讲默认的这种链接每一个评论都是一个外链,会分散站点的权重,就跟我们前文中所讲不要让友情链接在所有页面都显示是同样的道理,修改为重定向之后效果会好一些。
方法:在主题目录的functions.php的适当位置添加如下代码:
> //comments link redirect
> add_filter(‘get_comment_author_link’, ‘add_redirect_comment_link’, 5);
> add_filter(‘comment_text’, ‘add_redirect_comment_link’, 99);
> function add_redirect_comment_link($text = ”){
> $text=str_replace(‘href=”‘, ‘href=”‘.get_option(‘home’).’/?r=’, $text);
> $text=str_replace(“href='”, “href='”.get_option(‘home’).”/?r=”, $text);
> return $text;
> }
> add_action(‘init’, ‘redirect_comment_link’);
> function redirect_comment_link(){
> $redirect = $_GET[‘r’];
> if($redirect){
> if(strpos($_SERVER[‘HTTP_REFERER’],get_option(‘home’)) !== false){
> header(“Location: $redirect”);
> exit;
> }
> else {
> header(“Location: [http://你的网址/”); ](http://你的网址/%22);)exit;
> }
> }
> }
当然 ,如果你还有特殊需求,也可以重定向控制评论框中的文本的URL链接。
**二:评论链接新窗口打开:**
WordPress默认的评论者链接都是在同一个窗口中打开的,访客点击评论者链接之后就离开了你的站,
也就没有了回头客,很多时候流量就是在这个时候丢失的。
方法:在wp-includes/comment-template.php中增加一个target=‘_blank’语句。
即在这段代码:
> if ( empty( $url ) || ‘http://’ == $url )
> $return = $author;
> else
> $return = “<a rel=”external nofollow” href=”$url”>$author</a>”;
> return apply_filters(‘get_comment_author_link’, $return);
中的第一句rel=”external nofollow”后面增加一个target=”_blank”。
最后,建议在robots.txt中增加一行:Disallow: /?r=* 告诉搜索引擎不要抓取此页面,至此整个修改已经大功告成,刷新浏览器所见即所得。
