Commit 03f9eb95 authored by JC Brand's avatar JC Brand

Fixes #1467. Fix rendering of URLs enclosed with sharp brackets

such as <https://example.org>
parent cbc34311
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
- #1407: Silent errors when trying to use whitespace as MUC nickname - #1407: Silent errors when trying to use whitespace as MUC nickname
- #1437: List of groupchats in modal doesn't scroll - #1437: List of groupchats in modal doesn't scroll
- #1457: Wrong tooltip shown for "unbookmark" icon - #1457: Wrong tooltip shown for "unbookmark" icon
- #1467: Fix rendering of URLs enclosed with sharp brackets such as <https://example.org>
- #1479: Allow file upload by drag & drop also in MUCs - #1479: Allow file upload by drag & drop also in MUCs
- #1487: New config option [muc_respect_autojoin](https://conversejs.org/docs/html/configuration.html#muc-respect-autojoin) - #1487: New config option [muc_respect_autojoin](https://conversejs.org/docs/html/configuration.html#muc-respect-autojoin)
- #1501: Don't prompt for a reason if [auto_join_on_invite](https://conversejs.org/docs/html/configuration.html#auto-join-on-invite) is `true` - #1501: Don't prompt for a reason if [auto_join_on_invite](https://conversejs.org/docs/html/configuration.html#auto-join-on-invite) is `true`
......
This diff is collapsed.
...@@ -897,12 +897,21 @@ ...@@ -897,12 +897,21 @@
expect(msg.textContent).toEqual(message); expect(msg.textContent).toEqual(message);
expect(msg.innerHTML).toEqual('<a target="_blank" rel="noopener" href="https://en.wikipedia.org/wiki/Ender%27s_Game">'+message+'</a>'); expect(msg.innerHTML).toEqual('<a target="_blank" rel="noopener" href="https://en.wikipedia.org/wiki/Ender%27s_Game">'+message+'</a>');
message = "https://en.wikipedia.org/wiki/Ender's_Game"; message = "<https://bugs.documentfoundation.org/show_bug.cgi?id=123737>";
await test_utils.sendMessage(view, message); await test_utils.sendMessage(view, message);
msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view.el).pop(); msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view.el).pop();
expect(msg.textContent).toEqual(message); expect(msg.textContent).toEqual(message);
expect(msg.innerHTML).toEqual('<a target="_blank" rel="noopener" href="https://en.wikipedia.org/wiki/Ender%27s_Game">'+message+'</a>'); expect(msg.innerHTML).toEqual(
`&lt;<a target="_blank" rel="noopener" href="https://bugs.documentfoundation.org/show_bug.cgi?id=123737">https://bugs.documentfoundation.org/show_bug.cgi?id=123737</a>&gt;`);
message = '<http://www.opkode.com/"onmouseover="alert(1)"whatever>';
await test_utils.sendMessage(view, message);
msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view.el).pop();
expect(msg.textContent).toEqual(message);
expect(msg.innerHTML).toEqual(
'&lt;<a target="_blank" rel="noopener" href="http://www.opkode.com/%22onmouseover=%22alert%281%29%22whatever">http://www.opkode.com/"onmouseover="alert(1)"whatever</a>&gt;');
done(); done();
})); }));
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
// Copyright (c) 2013-2019, the Converse.js developers // Copyright (c) 2013-2019, the Converse.js developers
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
import URI from "urijs";
import converse from "@converse/headless/converse-core"; import converse from "@converse/headless/converse-core";
import filesize from "filesize"; import filesize from "filesize";
import html from "./utils/html"; import html from "./utils/html";
...@@ -30,6 +31,36 @@ converse.plugins.add('converse-message-view', { ...@@ -30,6 +31,36 @@ converse.plugins.add('converse-message-view', {
{ __ } = _converse; { __ } = _converse;
function onTagFoundDuringXSSFilter (tag, html, options) {
/* This function gets called by the XSS library whenever it finds
* what it thinks is a new HTML tag.
*
* It thinks that something like <https://example.com> is an HTML
* tag and then escapes the <> chars.
*
* We want to avoid this, because it prevents these URLs from being
* shown properly (whithout the trailing &gt;).
*
* The URI lib correctly trims a trailing >, but not a trailing &gt;
*/
if (options.isClosing) {
// Closing tags don't match our use-case
return;
}
const uri = new URI(tag);
const protocol = uri.protocol().toLowerCase();
if (!_.includes(["https", "http", "xmpp", "ftp"], protocol)) {
// Not a URL, the tag will get filtered as usual
return;
}
if (uri.equals(tag) && `<${tag}>` === html.toLocaleLowerCase()) {
// We have something like <https://example.com>, and don't want
// to filter it.
return html;
}
}
_converse.api.settings.update({ _converse.api.settings.update({
'show_images_inline': true 'show_images_inline': true
}); });
...@@ -146,7 +177,7 @@ converse.plugins.add('converse-message-view', { ...@@ -146,7 +177,7 @@ converse.plugins.add('converse-message-view', {
if (is_me_message) { if (is_me_message) {
text = text.substring(4); text = text.substring(4);
} }
text = xss.filterXSS(text, {'whiteList': {}}); text = xss.filterXSS(text, {'whiteList': {}, 'onTag': onTagFoundDuringXSSFilter});
msg_content.innerHTML = _.flow( msg_content.innerHTML = _.flow(
_.partial(u.geoUriToHttp, _, _converse.geouri_replacement), _.partial(u.geoUriToHttp, _, _converse.geouri_replacement),
_.partial(u.addMentionsMarkup, _, this.model.get('references'), this.model.collection.chatbox), _.partial(u.addMentionsMarkup, _, this.model.get('references'), this.model.collection.chatbox),
......
...@@ -138,7 +138,6 @@ u.renderFileURL = function (_converse, url) { ...@@ -138,7 +138,6 @@ u.renderFileURL = function (_converse, url) {
}) })
}; };
u.renderImageURL = function (_converse, url) { u.renderImageURL = function (_converse, url) {
if (!_converse.show_images_inline) { if (!_converse.show_images_inline) {
return u.addHyperlinks(url); return u.addHyperlinks(url);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment