Tighten up security around unfurls
Dont render OGP metadata: - for URLs not actually found in the original message - from MUC participants (only from the MUC itself)
This commit is contained in:
parent
49837c2da4
commit
426bf1d631
@ -911,7 +911,7 @@ describe("Chatboxes", function () {
|
|||||||
|
|
||||||
describe("Special Messages", function () {
|
describe("Special Messages", function () {
|
||||||
|
|
||||||
fit("'/clear' can be used to clear messages in a conversation",
|
it("'/clear' can be used to clear messages in a conversation",
|
||||||
mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
|
mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
|
||||||
|
|
||||||
await mock.waitForRoster(_converse, 'current');
|
await mock.waitForRoster(_converse, 'current');
|
||||||
|
@ -89,7 +89,7 @@ describe("A Groupchat Message", function () {
|
|||||||
metadata_stanza = u.toStanza(`
|
metadata_stanza = u.toStanza(`
|
||||||
<message xmlns="jabber:client" from="${muc_jid}" to="${_converse.jid}" type="groupchat">
|
<message xmlns="jabber:client" from="${muc_jid}" to="${_converse.jid}" type="groupchat">
|
||||||
<apply-to xmlns="urn:xmpp:fasten:0" id="eda6c790-b4f3-4c07-b5e2-13fff99e6c04">
|
<apply-to xmlns="urn:xmpp:fasten:0" id="eda6c790-b4f3-4c07-b5e2-13fff99e6c04">
|
||||||
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:url" content="https://duckduckgo.com/" />
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:url" content="https://duckduckgo.com" />
|
||||||
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:site_name" content="DuckDuckGo" />
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:site_name" content="DuckDuckGo" />
|
||||||
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:image" content="https://duckduckgo.com/assets/logo_social-media.png" />
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:image" content="https://duckduckgo.com/assets/logo_social-media.png" />
|
||||||
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:title" content="DuckDuckGo - Privacy, simplified." />
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:title" content="DuckDuckGo - Privacy, simplified." />
|
||||||
@ -101,4 +101,96 @@ describe("A Groupchat Message", function () {
|
|||||||
await u.waitUntil(() => view.querySelectorAll('converse-message-unfurl').length === 2);
|
await u.waitUntil(() => view.querySelectorAll('converse-message-unfurl').length === 2);
|
||||||
done();
|
done();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
it("will not render an unfurl based on a URL not in the original message", mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
|
||||||
|
const nick = 'romeo';
|
||||||
|
const muc_jid = 'lounge@montague.lit';
|
||||||
|
await mock.openAndEnterChatRoom(_converse, muc_jid, nick);
|
||||||
|
const view = _converse.api.chatviews.get(muc_jid);
|
||||||
|
|
||||||
|
const message_stanza = u.toStanza(`
|
||||||
|
<message xmlns="jabber:client" type="groupchat" from="${muc_jid}/arzu" xml:lang="en" to="${_converse.jid}" id="eda6c790-b4f3-4c07-b5e2-13fff99e6c04">
|
||||||
|
<body>https://www.youtube.com/watch?v=dQw4w9WgXcQ</body>
|
||||||
|
<active xmlns="http://jabber.org/protocol/chatstates"/>
|
||||||
|
<origin-id xmlns="urn:xmpp:sid:0" id="eda6c790-b4f3-4c07-b5e2-13fff99e6c04"/>
|
||||||
|
<stanza-id xmlns="urn:xmpp:sid:0" by="${muc_jid}" id="8f7613cc-27d4-40ca-9488-da25c4baf92a"/>
|
||||||
|
<markable xmlns="urn:xmpp:chat-markers:0"/>
|
||||||
|
</message>`);
|
||||||
|
_converse.connection._dataRecv(mock.createRequest(message_stanza));
|
||||||
|
const el = await u.waitUntil(() => view.querySelector('.chat-msg__text'));
|
||||||
|
expect(el.textContent).toBe('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
|
||||||
|
|
||||||
|
spyOn(view.model, 'handleMetadataFastening').and.callThrough();
|
||||||
|
|
||||||
|
const metadata_stanza = u.toStanza(`
|
||||||
|
<message xmlns="jabber:client" from="${muc_jid}" to="${_converse.jid}" type="groupchat">
|
||||||
|
<apply-to xmlns="urn:xmpp:fasten:0" id="eda6c790-b4f3-4c07-b5e2-13fff99e6c04">
|
||||||
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:site_name" content="YouTube" />
|
||||||
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:url" content="https://www.youtube.com/watch?v=tmY-G6sngk8" />
|
||||||
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:title" content="Rick Astley - Never Gonna Give You Up (Video)" />
|
||||||
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:image" content="https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg" />
|
||||||
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:image:width" content="1280" />
|
||||||
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:image:height" content="720" />
|
||||||
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:description" content="Rick Astley&#39;s official music video for "Never Gonna Give You Up" Listen to Rick Astley: https://RickAstley.lnk.to/_listenYD Subscribe to the official Rick Ast..." />
|
||||||
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:type" content="video.other" />
|
||||||
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:video:url" content="https://www.youtube.com/embed/dQw4w9WgXcQ" />
|
||||||
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:video:secure_url" content="https://www.youtube.com/embed/dQw4w9WgXcQ" />
|
||||||
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:video:type" content="text/html" />
|
||||||
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:video:width" content="1280" />
|
||||||
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:video:height" content="720" />
|
||||||
|
</apply-to>
|
||||||
|
</message>`);
|
||||||
|
_converse.connection._dataRecv(mock.createRequest(metadata_stanza));
|
||||||
|
|
||||||
|
await u.waitUntil(() => view.model.handleMetadataFastening.calls.count());
|
||||||
|
expect(view.model.handleMetadataFastening.calls.first().returnValue).toBe(false);
|
||||||
|
expect(view.querySelector('converse-message-unfurl')).toBe(null);
|
||||||
|
done();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it("will not render an unfurl received from a MUC participant", mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
|
||||||
|
const nick = 'romeo';
|
||||||
|
const muc_jid = 'lounge@montague.lit';
|
||||||
|
await mock.openAndEnterChatRoom(_converse, muc_jid, nick);
|
||||||
|
const view = _converse.api.chatviews.get(muc_jid);
|
||||||
|
|
||||||
|
const message_stanza = u.toStanza(`
|
||||||
|
<message xmlns="jabber:client" type="groupchat" from="${muc_jid}/arzu" xml:lang="en" to="${_converse.jid}" id="eda6c790-b4f3-4c07-b5e2-13fff99e6c04">
|
||||||
|
<body>https://www.youtube.com/watch?v=dQw4w9WgXcQ</body>
|
||||||
|
<active xmlns="http://jabber.org/protocol/chatstates"/>
|
||||||
|
<origin-id xmlns="urn:xmpp:sid:0" id="eda6c790-b4f3-4c07-b5e2-13fff99e6c04"/>
|
||||||
|
<stanza-id xmlns="urn:xmpp:sid:0" by="${muc_jid}" id="8f7613cc-27d4-40ca-9488-da25c4baf92a"/>
|
||||||
|
<markable xmlns="urn:xmpp:chat-markers:0"/>
|
||||||
|
</message>`);
|
||||||
|
_converse.connection._dataRecv(mock.createRequest(message_stanza));
|
||||||
|
const el = await u.waitUntil(() => view.querySelector('.chat-msg__text'));
|
||||||
|
expect(el.textContent).toBe('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
|
||||||
|
|
||||||
|
spyOn(view.model, 'handleMetadataFastening').and.callThrough();
|
||||||
|
|
||||||
|
const metadata_stanza = u.toStanza(`
|
||||||
|
<message xmlns="jabber:client" from="${muc_jid}/arzu" to="${_converse.jid}" type="groupchat">
|
||||||
|
<apply-to xmlns="urn:xmpp:fasten:0" id="eda6c790-b4f3-4c07-b5e2-13fff99e6c04">
|
||||||
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:site_name" content="YouTube" />
|
||||||
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:url" content="https://www.youtube.com/watch?v=dQw4w9WgXcQ" />
|
||||||
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:title" content="Rick Astley - Never Gonna Give You Up (Video)" />
|
||||||
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:image" content="https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg" />
|
||||||
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:image:width" content="1280" />
|
||||||
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:image:height" content="720" />
|
||||||
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:description" content="Rick Astley&#39;s official music video for "Never Gonna Give You Up" Listen to Rick Astley: https://RickAstley.lnk.to/_listenYD Subscribe to the official Rick Ast..." />
|
||||||
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:type" content="video.other" />
|
||||||
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:video:url" content="https://www.youtube.com/embed/dQw4w9WgXcQ" />
|
||||||
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:video:secure_url" content="https://www.youtube.com/embed/dQw4w9WgXcQ" />
|
||||||
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:video:type" content="text/html" />
|
||||||
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:video:width" content="1280" />
|
||||||
|
<meta xmlns="http://www.w3.org/1999/xhtml" property="og:video:height" content="720" />
|
||||||
|
</apply-to>
|
||||||
|
</message>`);
|
||||||
|
_converse.connection._dataRecv(mock.createRequest(metadata_stanza));
|
||||||
|
|
||||||
|
await u.waitUntil(() => view.model.handleMetadataFastening.calls.count());
|
||||||
|
expect(view.model.handleMetadataFastening.calls.first().returnValue).toBe(false);
|
||||||
|
expect(view.querySelector('converse-message-unfurl')).toBe(null);
|
||||||
|
done();
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
|
@ -13,24 +13,6 @@ const { Strophe, $msg } = converse.env;
|
|||||||
|
|
||||||
const u = converse.env.utils;
|
const u = converse.env.utils;
|
||||||
|
|
||||||
const METADATA_ATTRIBUTES = [
|
|
||||||
"og:description",
|
|
||||||
"og:image",
|
|
||||||
"og:image:height",
|
|
||||||
"og:image:width",
|
|
||||||
"og:site_name",
|
|
||||||
"og:title",
|
|
||||||
"og:type",
|
|
||||||
"og:url",
|
|
||||||
"og:video:height",
|
|
||||||
"og:video:secure_url",
|
|
||||||
"og:video:tag",
|
|
||||||
"og:video:type",
|
|
||||||
"og:video:url",
|
|
||||||
"og:video:width"
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an open/ongoing chat conversation.
|
* Represents an open/ongoing chat conversation.
|
||||||
*
|
*
|
||||||
@ -488,20 +470,6 @@ const ChatBox = ModelWithContact.extend({
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
handleMetadataFastening (attrs) {
|
|
||||||
if (attrs.ogp_for_id) {
|
|
||||||
const message = this.messages.findWhere({'origin_id': attrs.ogp_for_id});
|
|
||||||
if (message) {
|
|
||||||
const list = [...(message.get('ogp_metadata') || []), pick(attrs, METADATA_ATTRIBUTES)];
|
|
||||||
message.save('ogp_metadata', list);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether the passed in message attributes represent a
|
* Determines whether the passed in message attributes represent a
|
||||||
* message which corrects a previously received message, or an
|
* message which corrects a previously received message, or an
|
||||||
|
@ -16,6 +16,23 @@ const ADMIN_COMMANDS = ['admin', 'ban', 'deop', 'destroy', 'member', 'op', 'revo
|
|||||||
const MODERATOR_COMMANDS = ['kick', 'mute', 'voice', 'modtools'];
|
const MODERATOR_COMMANDS = ['kick', 'mute', 'voice', 'modtools'];
|
||||||
const VISITOR_COMMANDS = ['nick'];
|
const VISITOR_COMMANDS = ['nick'];
|
||||||
|
|
||||||
|
const METADATA_ATTRIBUTES = [
|
||||||
|
"og:description",
|
||||||
|
"og:image",
|
||||||
|
"og:image:height",
|
||||||
|
"og:image:width",
|
||||||
|
"og:site_name",
|
||||||
|
"og:title",
|
||||||
|
"og:type",
|
||||||
|
"og:url",
|
||||||
|
"og:video:height",
|
||||||
|
"og:video:secure_url",
|
||||||
|
"og:video:tag",
|
||||||
|
"og:video:type",
|
||||||
|
"og:video:url",
|
||||||
|
"og:video:width"
|
||||||
|
];
|
||||||
|
|
||||||
const ACTION_INFO_CODES = ['301', '303', '333', '307', '321', '322'];
|
const ACTION_INFO_CODES = ['301', '303', '333', '307', '321', '322'];
|
||||||
|
|
||||||
const MUCSession = Model.extend({
|
const MUCSession = Model.extend({
|
||||||
@ -2104,6 +2121,29 @@ const ChatRoomMixin = {
|
|||||||
window.setTimeout(() => this.removeNotification(actor, state), 10000);
|
window.setTimeout(() => this.removeNotification(actor, state), 10000);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
handleMetadataFastening (attrs) {
|
||||||
|
if (attrs.ogp_for_id) {
|
||||||
|
if (attrs.from !== this.get('jid')) {
|
||||||
|
// For now we only allow metadata from the MUC itself and not
|
||||||
|
// from individual users who are deemed less trustworthy.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const message = this.messages.findWhere({'origin_id': attrs.ogp_for_id});
|
||||||
|
if (message) {
|
||||||
|
if (!attrs['og:url'] || !message.get('body').includes(attrs['og:url'])) {
|
||||||
|
// For security purposes, we don't show metadata for a URL not actually
|
||||||
|
// included in the original message
|
||||||
|
log.warn("Not showing OGP data because we can't find the relevant URL in the original message");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const list = [...(message.get('ogp_metadata') || []), pick(attrs, METADATA_ATTRIBUTES)];
|
||||||
|
message.save('ogp_metadata', list);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler for all MUC messages sent to this groupchat. This method
|
* Handler for all MUC messages sent to this groupchat. This method
|
||||||
* shouldn't be called directly, instead {@link _converse.ChatRoom#queueMessage}
|
* shouldn't be called directly, instead {@link _converse.ChatRoom#queueMessage}
|
||||||
|
Loading…
Reference in New Issue
Block a user