SECURITY: XSS when displaying watched words in admin panel.

SECURITY: XSS when displaying watched words in admin panel.

The XSS here is only possible if CSP is disabled. Low impact since CSP is enabled by default in SiteSettings.

diff --git a/app/assets/javascripts/admin/components/admin-watched-word.js.es6 b/app/assets/javascripts/admin/components/admin-watched-word.js.es6
index bed9bb2..4da1828 100644
--- a/app/assets/javascripts/admin/components/admin-watched-word.js.es6
+++ b/app/assets/javascripts/admin/components/admin-watched-word.js.es6
@@ -1,5 +1,6 @@
 import { iconHTML } from "discourse-common/lib/icon-library";
 import { bufferedRender } from "discourse-common/lib/buffered-render";
+import { escapeExpression } from "discourse/lib/utilities";
 
 export default Ember.Component.extend(
   bufferedRender({
@@ -7,7 +8,7 @@ export default Ember.Component.extend(
 
     buildBuffer(buffer) {
       buffer.push(iconHTML("times"));
-      buffer.push(" " + this.get("word.word"));
+      buffer.push(` ${escapeExpression(this.get("word.word"))}`);
     },
 
     click() {
diff --git a/test/javascripts/acceptance/admin-watched-words-test.js.es6 b/test/javascripts/acceptance/admin-watched-words-test.js.es6
index ca255a0..0f5b741 100644
--- a/test/javascripts/acceptance/admin-watched-words-test.js.es6
+++ b/test/javascripts/acceptance/admin-watched-words-test.js.es6
@@ -32,6 +32,12 @@ QUnit.test("list words in groups", async assert => {
     "Always show the words when checkbox is checked."
   );
 
+  assert.equal(
+    $(find(".watched-words-list .watched-word")[2]).text(),
+    ' <img src="x">',
+    "it should escape watched words"
+  );
+
   await click(".nav-stacked .censor a");
 
   assert.ok(exists(".watched-words-list"));
diff --git a/test/javascripts/fixtures/watched-words-fixtures.js.es6 b/test/javascripts/fixtures/watched-words-fixtures.js.es6
index 4ac0dee..14c180f 100644
--- a/test/javascripts/fixtures/watched-words-fixtures.js.es6
+++ b/test/javascripts/fixtures/watched-words-fixtures.js.es6
@@ -6,7 +6,8 @@ export default {
       { id: 2, word: "anise", action: "block" },
       { id: 3, word: "pyramid", action: "flag" },
       { id: 4, word: "scheme", action: "flag" },
-      { id: 5, word: "coupon", action: "require_approval" }
+      { id: 5, word: "coupon", action: "require_approval" },
+      { id: 6, word: '<img src="x">', action: "block" },
     ]
   }
 };

GitHub sha: 4b0cf7f6

1 Like

Fix the build.