SECURITY: Escape HTML in dashboard report tables

SECURITY: Escape HTML in dashboard report tables

diff --git a/app/assets/javascripts/admin/models/report.js.es6 b/app/assets/javascripts/admin/models/report.js.es6
index 21caf4a..d453dd0 100644
--- a/app/assets/javascripts/admin/models/report.js.es6
+++ b/app/assets/javascripts/admin/models/report.js.es6
@@ -333,7 +333,7 @@ const Report = Discourse.Model.extend({
     const formatedValue = () => {
       const topicId = row[properties.id];
       const href = Discourse.getURL(`/t/-/${topicId}`);
-      return `<a href='${href}'>${topicTitle}</a>`;
+      return `<a href='${href}'>${escapeExpression(topicTitle)}</a>`;
     };
 
     return {
@@ -352,7 +352,7 @@ const Report = Discourse.Model.extend({
       property: properties.title,
       value: postTitle,
       formatedValue:
-        postTitle && href ? `<a href='${href}'>${postTitle}</a>` : "—"
+        postTitle && href ? `<a href='${href}'>${escapeExpression(postTitle)}</a>` : "—"
     };
   },
 
diff --git a/test/javascripts/models/report-test.js.es6 b/test/javascripts/models/report-test.js.es6
index 3f1dd7a..3ba6a51 100644
--- a/test/javascripts/models/report-test.js.es6
+++ b/test/javascripts/models/report-test.js.es6
@@ -402,9 +402,9 @@ QUnit.test("computed labels", assert => {
       time_read: 287362,
       note: "This is a long note",
       topic_id: 2,
-      topic_title: "Test topic",
+      topic_title: "Test topic <html>",
       post_number: 3,
-      post_raw: "This is the beginning of",
+      post_raw: "This is the beginning of <html>",
       filesize: 582641
     }
   ];
@@ -502,9 +502,9 @@ QUnit.test("computed labels", assert => {
   const computedTopicLabel = topicLabel.compute(row);
   assert.equal(
     computedTopicLabel.formatedValue,
-    "<a href='/t/-/2'>Test topic</a>"
+    "<a href='/t/-/2'>Test topic &lt;html&gt;</a>"
   );
-  assert.equal(computedTopicLabel.value, "Test topic");
+  assert.equal(computedTopicLabel.value, "Test topic <html>");
 
   const postLabel = computedLabels[5];
   assert.equal(postLabel.mainProperty, "post_raw");
@@ -514,9 +514,9 @@ QUnit.test("computed labels", assert => {
   const computedPostLabel = postLabel.compute(row);
   assert.equal(
     computedPostLabel.formatedValue,
-    "<a href='/t/-/2/3'>This is the beginning of</a>"
+    "<a href='/t/-/2/3'>This is the beginning of &lt;html&gt;</a>"
   );
-  assert.equal(computedPostLabel.value, "This is the beginning of");
+  assert.equal(computedPostLabel.value, "This is the beginning of <html>");
 
   const filesizeLabel = computedLabels[6];
   assert.equal(filesizeLabel.mainProperty, "filesize");
@@ -533,11 +533,11 @@ QUnit.test("computed labels", assert => {
   const postLink = computedLabels[5].compute(row).formatedValue;
   assert.equal(
     postLink,
-    "<a href='/forum/t/-/2/3'>This is the beginning of</a>"
+    "<a href='/forum/t/-/2/3'>This is the beginning of &lt;html&gt;</a>"
   );
 
   const topicLink = computedLabels[4].compute(row).formatedValue;
-  assert.equal(topicLink, "<a href='/forum/t/-/2'>Test topic</a>");
+  assert.equal(topicLink, "<a href='/forum/t/-/2'>Test topic &lt;html&gt;</a>");
 
   const userLink = computedLabels[0].compute(row).formatedValue;
   assert.equal(

GitHub sha: 5c9426be

1 Like