]> source.dussan.org Git - sonarqube.git/commitdiff
Fix SSF-241
authorZipeng WU <zipeng.wu@sonarsource.com>
Wed, 30 Mar 2022 10:40:24 +0000 (12:40 +0200)
committersonartech <sonartech@sonarsource.com>
Thu, 31 Mar 2022 20:02:42 +0000 (20:02 +0000)
server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/IssueChangesEmailTemplate.java
server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/ChangesOnMyIssuesEmailTemplateTest.java

index d717bf2f1543342965b6f52ed000061cd1a4e892..4d1ad1e6a1c092e84260b7c352af4fb03fd455e9 100644 (file)
@@ -46,6 +46,7 @@ import org.sonar.server.issue.notification.IssuesChangesNotificationBuilder.Rule
 import static java.net.URLEncoder.encode;
 import static java.nio.charset.StandardCharsets.UTF_8;
 import static java.util.function.Function.identity;
+import static org.apache.commons.lang.StringEscapeUtils.escapeHtml;
 import static org.sonar.core.util.stream.MoreCollectors.index;
 import static org.sonar.server.issue.notification.RuleGroup.ISSUES;
 import static org.sonar.server.issue.notification.RuleGroup.SECURITY_HOTSPOTS;
@@ -85,11 +86,11 @@ public abstract class IssueChangesEmailTemplate implements EmailTemplate {
    */
   protected static void toString(StringBuilder sb, Project project) {
     Optional<String> branchName = project.getBranchName();
+    String value = project.getProjectName();
     if (branchName.isPresent()) {
-      sb.append(project.getProjectName()).append(", ").append(branchName.get());
-    } else {
-      sb.append(project.getProjectName());
+      value += ", " + branchName.get();
     }
+    sb.append(escapeHtml(value));
   }
 
   static String toUrlParams(Project project) {
@@ -155,7 +156,8 @@ public abstract class IssueChangesEmailTemplate implements EmailTemplate {
       Rule rule = rules.next();
       Collection<ChangedIssue> issues = issuesByRule.get(rule);
 
-      sb.append("<li>").append("Rule ").append(" <em>").append(rule.getName()).append("</em> - ");
+      String ruleName = escapeHtml(rule.getName());
+      sb.append("<li>").append("Rule ").append(" <em>").append(ruleName).append("</em> - ");
       appendIssueLinks(sb, issuePageHref, issues, rule.getRuleType());
       sb.append("</li>");
     }
index 4b57f1288fddcf536af8798d0ac73e9875857f4a..dc772e1967ff217838543e16ce8b1e56448b4bea 100644 (file)
@@ -54,6 +54,7 @@ import static java.util.stream.Collectors.joining;
 import static java.util.stream.Collectors.toList;
 import static java.util.stream.Collectors.toSet;
 import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
+import static org.apache.commons.lang.StringEscapeUtils.escapeHtml;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -412,6 +413,38 @@ public class ChangesOnMyIssuesEmailTemplateTest {
       .noMoreBlock();
   }
 
+  @Test
+  public void user_input_content_should_be_html_escape() {
+    Project project = new Project.Builder("uuid").setProjectName("</projectName>").setKey("project_key").build();
+    String ruleName = "</RandomRule>";
+    String host = randomAlphabetic(15);
+    Rule rule = newRule(ruleName, randomRuleTypeHotspotExcluded());
+    List<ChangedIssue> changedIssues = IntStream.range(0, 2 + new Random().nextInt(5))
+      .mapToObj(i -> newChangedIssue("issue_" + i, randomValidStatus(), project, rule))
+      .collect(toList());
+    UserChange userChange = newUserChange();
+    when(emailSettings.getServerBaseURL()).thenReturn(host);
+
+    EmailMessage emailMessage = underTest.format(new ChangesOnMyIssuesNotification(userChange, ImmutableSet.copyOf(changedIssues)));
+
+    assertThat(emailMessage.getMessage())
+      .doesNotContain(project.getProjectName())
+      .contains(escapeHtml(project.getProjectName()))
+      .doesNotContain(ruleName)
+      .contains(escapeHtml(ruleName));
+
+    String expectedHref = host + "/project/issues?id=" + project.getKey()
+      + "&issues=" + changedIssues.stream().map(ChangedIssue::getKey).collect(joining("%2C"));
+    String expectedLinkText = "See all " + changedIssues.size() + " issues";
+    HtmlFragmentAssert.assertThat(emailMessage.getMessage())
+      .hasParagraph().hasParagraph() // skip header
+      .hasParagraph(project.getProjectName())
+      .hasList("Rule " + ruleName + " - " + expectedLinkText)
+      .withLink(expectedLinkText, expectedHref)
+      .hasParagraph().hasParagraph() // skip footer
+      .noMoreBlock();
+  }
+
   @Test
   public void formats_returns_html_message_for_single_issue_on_master_when_user_change() {
     Project project = newProject("1");