From 4489b5a21aa7550d1bfeee1b4f3960ebc4698cb7 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Sat, 28 Dec 2019 20:05:55 +0000
Subject: [PATCH 1/3] Escape HTML in og:description and render any html
&-encoded entities
---
src/components/views/rooms/LinkPreviewWidget.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/components/views/rooms/LinkPreviewWidget.js b/src/components/views/rooms/LinkPreviewWidget.js
index ee63cd1bb7..06c0201af8 100644
--- a/src/components/views/rooms/LinkPreviewWidget.js
+++ b/src/components/views/rooms/LinkPreviewWidget.js
@@ -128,15 +128,15 @@ module.exports = createReactClass({
}
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
+ // Escape > to prevent any HTML injections, we can't replace & as the description may contain & encoded html entities
+ const safeDescription = (p["og:description"] || "").replace("<", "<").replace(">", ">");
return (
{ img }
{ p["og:site_name"] ? (" - " + p["og:site_name"]) : null }
-
- { p["og:description"] }
-
+
Date: Sun, 5 Jan 2020 22:22:09 +0000
Subject: [PATCH 2/3] Use html-entities instead
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
---
package.json | 3 ++-
src/components/views/rooms/LinkPreviewWidget.js | 10 ++++++----
yarn.lock | 5 +++++
3 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/package.json b/package.json
index 7ef14e6635..7e2c242b3a 100644
--- a/package.json
+++ b/package.json
@@ -74,7 +74,6 @@
"file-saver": "^1.3.3",
"filesize": "3.5.6",
"flux": "2.1.1",
- "react-focus-lock": "^2.2.1",
"focus-visible": "^5.0.2",
"fuse.js": "^2.2.0",
"gemini-scrollbar": "github:matrix-org/gemini-scrollbar#91e1e566",
@@ -82,6 +81,7 @@
"glob": "^5.0.14",
"glob-to-regexp": "^0.4.1",
"highlight.js": "^9.15.8",
+ "html-entities": "^1.2.1",
"is-ip": "^2.0.0",
"isomorphic-fetch": "^2.2.1",
"linkifyjs": "^2.1.6",
@@ -99,6 +99,7 @@
"react-addons-css-transition-group": "15.6.2",
"react-beautiful-dnd": "^4.0.1",
"react-dom": "^16.9.0",
+ "react-focus-lock": "^2.2.1",
"react-gemini-scrollbar": "github:matrix-org/react-gemini-scrollbar#9cf17f63b7c0b0ec5f31df27da0f82f7238dc594",
"resize-observer-polyfill": "^1.5.0",
"sanitize-html": "^1.18.4",
diff --git a/src/components/views/rooms/LinkPreviewWidget.js b/src/components/views/rooms/LinkPreviewWidget.js
index 06c0201af8..4822848233 100644
--- a/src/components/views/rooms/LinkPreviewWidget.js
+++ b/src/components/views/rooms/LinkPreviewWidget.js
@@ -18,7 +18,9 @@ limitations under the License.
import React, {createRef} from 'react';
import PropTypes from 'prop-types';
import createReactClass from 'create-react-class';
-import { linkifyElement } from '../../../HtmlUtils';
+import { AllHtmlEntities } from 'html-entities';
+
+import {linkifyElement} from '../../../HtmlUtils';
import SettingsStore from "../../../settings/SettingsStore";
import { _t } from "../../../languageHandler";
@@ -128,15 +130,15 @@ module.exports = createReactClass({
}
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
- // Escape > to prevent any HTML injections, we can't replace & as the description may contain & encoded html entities
- const safeDescription = (p["og:description"] || "").replace("<", "<").replace(">", ">");
return (
{ img }
{ p["og:site_name"] ? (" - " + p["og:site_name"]) : null }
-
+
+ { AllHtmlEntities.decode(p["og:description"] || "") }
+
Date: Mon, 6 Jan 2020 00:18:24 +0000
Subject: [PATCH 3/3] Add comment and delint
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
---
src/components/views/rooms/LinkPreviewWidget.js | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/components/views/rooms/LinkPreviewWidget.js b/src/components/views/rooms/LinkPreviewWidget.js
index 4822848233..3b5545e0e0 100644
--- a/src/components/views/rooms/LinkPreviewWidget.js
+++ b/src/components/views/rooms/LinkPreviewWidget.js
@@ -19,7 +19,6 @@ import React, {createRef} from 'react';
import PropTypes from 'prop-types';
import createReactClass from 'create-react-class';
import { AllHtmlEntities } from 'html-entities';
-
import {linkifyElement} from '../../../HtmlUtils';
import SettingsStore from "../../../settings/SettingsStore";
import { _t } from "../../../languageHandler";
@@ -129,6 +128,10 @@ module.exports = createReactClass({
;
}
+ // The description includes &-encoded HTML entities, we decode those as React treats the thing as an
+ // opaque string. This does not allow any HTML to be injected into the DOM.
+ const description = AllHtmlEntities.decode(p["og:description"] || "");
+
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
return (
@@ -137,7 +140,7 @@ module.exports = createReactClass({
{ p["og:site_name"] ? (" - " + p["og:site_name"]) : null }
- { AllHtmlEntities.decode(p["og:description"] || "") }
+ { description }