diff --git a/core/modules/node/src/Plugin/Search/NodeSearch.php b/core/modules/node/src/Plugin/Search/NodeSearch.php
index 87a3851c5d1..bab5cc953ec 100644
--- a/core/modules/node/src/Plugin/Search/NodeSearch.php
+++ b/core/modules/node/src/Plugin/Search/NodeSearch.php
@@ -332,11 +332,9 @@ class NodeSearch extends ConfigurableSearchPluginBase implements AccessibleInter
unset($build['#theme']);
$build['#pre_render'][] = array($this, 'removeSubmittedInfo');
- // Fetch comment count for snippet.
- $rendered = SafeMarkup::set(
- $this->renderer->renderPlain($build) . ' ' .
- SafeMarkup::escape($this->moduleHandler->invoke('comment', 'node_update_index', array($node, $item->langcode)))
- );
+ // Fetch comments for snippet.
+ $rendered = $this->renderer->renderPlain($build);
+ $rendered .= ' ' . $this->moduleHandler->invoke('comment', 'node_update_index', array($node, $item->langcode));
$extra = $this->moduleHandler->invokeAll('node_search_result', array($node, $item->langcode));
diff --git a/core/modules/search/search.module b/core/modules/search/search.module
index 25d52b53fab..e7ee180946d 100644
--- a/core/modules/search/search.module
+++ b/core/modules/search/search.module
@@ -618,7 +618,8 @@ function search_mark_for_reindex($type = NULL, $sid = NULL, $langcode = NULL) {
/**
* Returns snippets from a piece of text, with search keywords highlighted.
*
- * Used for formatting search results.
+ * Used for formatting search results. All HTML tags will be stripped from
+ * $text.
*
* @param string $keys
* A string containing a search query.
diff --git a/core/modules/search/src/Tests/SearchCommentTest.php b/core/modules/search/src/Tests/SearchCommentTest.php
index b9916e2bdbd..d7f72554195 100644
--- a/core/modules/search/src/Tests/SearchCommentTest.php
+++ b/core/modules/search/src/Tests/SearchCommentTest.php
@@ -126,6 +126,23 @@ class SearchCommentTest extends SearchTestBase {
$edit_comment['comment_body[0][format]'] = $full_html_format_id;
$this->drupalPostForm('comment/reply/node/' . $node->id() .'/comment', $edit_comment, t('Save'));
+ // Post a comment with an evil script tag in the comment subject and a
+ // script tag nearby a keyword in the comment body. Use the 'FULL HTML' text
+ // format so the script tag stored.
+ $edit_comment2 = array();
+ $edit_comment2['subject[0][value]'] = "";
+ $edit_comment2['comment_body[0][value]'] = "nearbykeyword";
+ $edit_comment2['comment_body[0][format]'] = $full_html_format_id;
+ $this->drupalPostForm('comment/reply/node/' . $node->id() . '/comment', $edit_comment2, t('Save'));
+
+ // Post a comment with a keyword inside an evil script tag in the comment
+ // body. Use the 'FULL HTML' text format so the script tag is stored.
+ $edit_comment3 = array();
+ $edit_comment3['subject[0][value]'] = 'asubject';
+ $edit_comment3['comment_body[0][value]'] = "";
+ $edit_comment3['comment_body[0][format]'] = $full_html_format_id;
+ $this->drupalPostForm('comment/reply/node/' . $node->id() . '/comment', $edit_comment3, t('Save'));
+
// Invoke search index update.
$this->drupalLogout();
$this->cronRun();
@@ -152,6 +169,39 @@ class SearchCommentTest extends SearchTestBase {
$this->assertNoRaw(t('n/a'), 'HTML in comment body is not hidden.');
$this->assertNoEscaped($edit_comment['comment_body[0][value]'], 'HTML in comment body is not escaped.');
+ // Search for the evil script comment subject.
+ $edit = array(
+ 'keys' => 'subjectkeyword',
+ );
+ $this->drupalPostForm('search/node', $edit, t('Search'));
+
+ // Verify the evil comment subject is escaped in search results.
+ $this->assertRaw('<script>alert('subjectkeyword');');
+ $this->assertNoRaw('