2026 maintenance note: This article is now a security guide for commenter links. The complete 2011 text remains at the end for provenance; do not execute its open redirect, referrer check, string replacement, or core-file edit.
Table of Contents
The short answer
Most sites do not need an intermediate redirect for commenter websites. Let WordPress emit a direct, sanitized and escaped URL that a moderator has reviewed, and open it in the current tab by default. That is usually the simplest and safest design.
Do not put a user-submitted URL in ?r= or ?to= and then redirect through your domain. A public endpoint like that turns your brand into a launch point for phishing and spam. Checking HTTP_REFERER does not fix it: referrer data may be absent, trimmed by privacy tools, or forged. esc_url() is suitable for output escaping, but does not make an arbitrary external destination trusted. `wp_safe_redirect()` is designed for safe local redirects, not for accepting a user-controlled off-site URL.
Choices and boundaries
| Need | Recommended approach | Do not use |
|---|---|---|
| Show a commenter website | Use the direct link generated by WordPress core and moderate the commenter URL | A public open-redirect endpoint |
| Reduce comment spam and link manipulation | Enable moderation, limit link counts, and use ugc; add nofollow when site policy calls for it | Disguise outbound links behind a local redirect or assume “link equity cannot leak” |
| Open a new tab | Only for a demonstrated user need, modify the generated <a> with supported filters and warn in advance | Core edits or str_replace() over HTML |
| Handle links in comment bodies | Use WordPress's built-in filtering, allowed HTML, and moderation workflow | Globally replace href throughout comment_text |
A commenter website is a public field. Comment email addresses, IP addresses, moderation tokens, and admin links containing tracking parameters are not. Do not put those values in public URLs, front-end HTML, screenshots, or diagnostic logs. Establish privacy and compliance boundaries first for sites serving children, regulated communities, or organizations with retention requirements.
Safe baseline: direct, moderated links
- Take a complete backup in staging and record the active theme, comment plugins, cache/CDN, and comment-page HTML. Search for old
?r=/?to=endpoints,HTTP_REFERERchecks,comment_textstring replacements, and edits underwp-includes. - Update WordPress, the theme, and comment plugins. Restore any modified core files. `wp core verify-checksums` can help identify core differences, but does not replace a backup or human review.
- Configure moderation appropriate to the community's risk in Settings → Discussion and the Comments screen. Do not click suspicious, typo-squatted, shortened, credential-bearing, or needlessly tracked commenter URLs; clear or reject the URL/comment.
- Have the theme call WordPress's comment-author APIs. The current `get_comment_author_link()` escapes the URL for output and constructs the link's
rel. Do not rebuild the link from an unescapedcomment_author_urlin a template. - Disable the old redirect logic in staging and review access logs for dependencies before shipping one bounded change. Do not retain the old endpoint as an arbitrary-destination redirect. If external dependencies exist, have a security owner define a fixed-target migration or an explicit retirement response.
The WordPress guides to comments, Discussion settings, and comment moderation are the starting points for public fields, moderation queues, and link thresholds. Moderation reduces risk; it cannot prove that a destination will remain safe forever.
rel describes a relationship; it is not SEO magic
WordPress 6.2 and later provide `comment_author_link_rel` to filter the rel tokens on commenter links. Current core adds ugc for user-generated content and constructs the relevant relationship based on whether the link is internal or external. Google likewise recommends `rel="ugc"` for links in comments or forums; nofollow may be combined with it when the site does not want to associate with the destination.
Usually, no code is needed. If site policy explicitly requires every commenter link to carry both ugc nofollow, put this WordPress 6.2+ filter in a small, deactivatable site plugin instead of editing core:
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
);
Confirm the deployed WordPress version and the final output of other plugins first. nofollow/ugc are relationship hints, not anti-spam, privacy isolation, or access control. Hiding a link behind a local redirect and then blocking it in robots.txt neither secures an open redirect nor guarantees rankings or the preservation of “link equity.” See Google's spam policies.
New tabs are optional and require advance notice
Keeping the current tab and its ordinary Back button is generally more predictable. If research and user feedback genuinely support a new tab, WCAG Technique G201 calls for warning users before opening a new window. The following WordPress 6.2+ example uses `WP_HTML_Tag_Processor` to modify attributes, preserves core's existing rel, and provides both visible and accessible-name notices:
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
);
Add the two English strings to the site plugin's translation catalog. noreferrer reduces disclosure of the source page to the destination, but also changes analytics data; obtain privacy and analytics approval before deployment. If WordPress 6.1 or earlier must be supported, upgrade rather than falling back to string replacement.
Why the old techniques are unsafe
- User-controlled redirect targets: Your domain vouches for any destination and can be abused for phishing, spam, and link-check bypass. Syntax cleanup is not destination authorization. If a business truly needs redirects, a security team should design a small server-side mapping of fixed, reviewed targets.
- Referrer gates:
HTTP_REFERERis not an authentication or authorization signal. It can be absent, leak a sensitive path, or be forged, so it rejects legitimate visitors without stopping attackers. str_replace()over HTML: It does not understand tag boundaries. It can rewrite comment bodies, internal links, single/double quotes, encoded attributes, or non-link text, and can create duplicate or broken attributes. Use a purpose-built hook and HTML parser.- WordPress core edits: An update overwrites them and makes patch auditing and incident rollback harder. WordPress's plugin basics document hooks as the extension path.
- The “link equity” myth: A redirect does not automatically erase the destination relationship, and
robots.txtis not a security boundary. Invest in real moderation, comment-spam controls, and accurate labeling of user-generated links.
Validate, release, and roll back
In staging, test at least: approved, pending, spam, and deleted comments; empty, internal, ordinary HTTPS, IDN/homograph, shortened, query-bearing, and rejected-scheme URLs; logged-in/out states; desktop/mobile themes; keyboard, screen-reader, and focus behavior; cache/CDN; feeds, REST API, and admin pages. Browser developer tools should show a direct, correctly escaped href, the expected rel, and no redirect query parameter by default.
Release one change at a time and retain the deployment record. Monitor 4xx responses, old redirect-endpoint traffic, moderation queues, and user reports. Keep only necessary log fields, and remove complete query strings, email addresses, IPs, tokens, and commenter personal information before sharing. If redirects loop, destinations are rewritten, plugins conflict, accessibility regresses, or the old endpoint still reaches an arbitrary external site, immediately deactivate the site plugin/restore the prior version, purge caches, and escalate to a WordPress or security owner.
Official sources
- WordPress: escaping output
- WordPress: `get_comment_author_link` filter
- WordPress: `comment_author_link_rel` filter
- WordPress: `WP_HTML_Tag_Processor`
- WordPress: comment moderation and understanding comment spam
- Google Search Central: qualify outbound links
- W3C WAI: warning when opening a new window
Historical source archive (do not execute)
This is the complete visible body of the 2011 source export, with trailing whitespace normalized only. Two live target classes were narrowly replaced: the site URL with
[REDACTED: historical site URL], and the open-redirect URL with[REDACTED: historical open-redirect URL]. To keep the complete body inside one inert fence in this site's Markdown engine, one zero-width fence breaker was inserted into each of the two inner triple-backtick markers; displayed text is unchanged. No other body text was rewritten. The code contains an open redirect, an unauthorized external redirect, a fragile referrer check, and a core-file edit. Do not copy, run, or deploy it.
```
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=* 告诉搜索引擎不要抓取此页面,至此整个修改已经大功告成,刷新浏览器所见即所得。
