Index: wp-admin/edit-comments.php
===================================================================
--- wp-admin/edit-comments.php	(revision 40266)
+++ wp-admin/edit-comments.php	(working copy)
@@ -16,6 +16,9 @@
 	);
 }
 
+//* TODO determine whether to move globally (i.e. filter "pre_comment_content"). Ticket #40916
+add_filter( 'comment_text', 'wp_unbind_links', 35 );
+
 $wp_list_table = _get_list_table('WP_Comments_List_Table');
 $pagenum = $wp_list_table->get_pagenum();
 
Index: wp-admin/includes/class-wp-comments-list-table.php
===================================================================
--- wp-admin/includes/class-wp-comments-list-table.php	(revision 40266)
+++ wp-admin/includes/class-wp-comments-list-table.php	(working copy)
@@ -440,7 +440,6 @@
 		$this->display_tablenav( 'top' );
 
 		$this->screen->render_screen_reader_content( 'heading_list' );
-
 ?>
 <table class="wp-list-table <?php echo implode( ' ', $this->get_table_classes() ); ?>">
 	<thead>
@@ -652,6 +651,7 @@
 		}
 
 		comment_text( $comment );
+
 		if ( $this->user_can ) { ?>
 		<div id="inline-<?php echo $comment->comment_ID; ?>" class="hidden">
 		<textarea class="comment" rows="1" cols="1"><?php
@@ -685,7 +685,8 @@
 
 		echo "<strong>"; comment_author( $comment ); echo '</strong><br />';
 		if ( ! empty( $author_url_display ) ) {
-			printf( '<a href="%s">%s</a><br />', esc_url( $author_url ), esc_html( $author_url_display ) );
+			// Ticket #40916
+			printf( '<a href="%s" rel="noopener noreferrer" target="_blank">%s</a><br />', esc_url( $author_url ), esc_html( $author_url_display ) );
 		}
 
 		if ( $this->user_can ) {
Index: wp-includes/formatting.php
===================================================================
--- wp-includes/formatting.php	(revision 40266)
+++ wp-includes/formatting.php	(working copy)
@@ -2758,6 +2758,65 @@
 }
 
 /**
+ * Adds target="_blank" and rel="noreferrer noopener" strings to all HTML A elements
+ * in content.
+ *
+ * Removes current target and rel attributes prior.
+ *
+ * @since TODO Ticket #40916
+ *
+ * @param string $text Content that may contain HTML A elements.
+ * @return string Converted content.
+ */
+function wp_unbind_links( $text ) {
+
+	// Ticket #40916 Filter usage to be determined...
+	if ( 'pre_comment_content' === current_filter() ) {
+		// This is a pre save filter, so text is already escaped.
+		$text = stripslashes( $text );
+		$text = preg_replace_callback( '|<a (.+?)>|i', 'wp_unbind_links_callback', $text );
+		return wp_slash( $text );
+	}
+
+	return preg_replace_callback( '|<a (.+?)>|i', 'wp_unbind_links_callback', $text );
+}
+
+/**
+ * Callback to add target="_blank" and rel="noreferrer noopener" string to HTML A element.
+ *
+ * Will remove already existing rel="noreferrer", rel='noreferrer', rel="noopener"
+ * and rel='noopener' from the string to prevent from invalidating (X)HTML.
+ *
+ * @since TODO Ticket #40916
+ *
+ * @param array $matches Single Match
+ * @return string HTML A Element with target="_blank" and rel="noreferrer noopener".
+ */
+function wp_unbind_links_callback( $matches ) {
+
+	$text = $matches[1];
+
+	// TODO Do we want to exclude own pages?
+	/*
+	if ( preg_match( '%href=["\'](https?' . preg_quote( str_replace( 'http://', '://', set_url_scheme( home_url(), 'http' ) ) ) . ')%i', $text ) ) {
+		return "<a $text>";
+	}
+	*/
+
+	/**
+	 * Captures rel and target attributes with content.
+	 * Closing/opening tag aware, i.e. it captures:
+	 * rel='nofollow"', rel="nofollow", rel=nofollow, rel="nofollow noreferrer"
+	 */
+	$regex = '/(target|rel)\=(\'|"?)((?:.(?!\2?\s+(?:\S+)=|[>]\2))+.)\2?/i';
+
+	//* TODO This will add stray whitespaces... It's not important enough to clean up.
+	$text = preg_replace( $regex, '', $text );
+
+	return sprintf( '<a %s target=_blank rel="noopener noreferrer">', $text );
+}
+
+/**
  * Convert one smiley code to the icon graphic file equivalent.
  *
  * Callback handler for convert_smilies().
