Summary: Rocket.Chat offers two different markdown parsers out of the box: the ’orginal’ one and the ’marked’ one. Both markdown parsers offer a different set of features with different re- strictions. Due to more loose restrictions in the ’marked’ parser, a persistent CSS injection in the web interface of Rocket.Chat is possible.
Description: Due to style injection in the complete chat window, an adversary is able to manipulate not only the style of it, but will also be able to block functionality as well as hijacking the content of targeted users. Hence the payloads are stored in messages, it is a persistent attack vector, which will trigger as soon as the message gets viewed.
(Add details for how we can reproduce the issue)
usertest
and a channel containing both accounts<div>foobar</div>
This should block the top right channel settings with a red box.
6. Send
foo
<style >
[data-username="usertest"] div div p{
background: rgba(255, 0, 0, 0.2);
font-size: 0;
}
[data-username="usertest"] div div p::after{ font-size: initial;
content: "hacked";
}
</style>
as admin user and observe, that the messages of ‘usertest’ are overwritten with the content ‘hacked’. (It can be done vice versa when replacing ‘usertest’ in the payload with the admins username).
The implementation of the ’marked’ render removes html encoding of the message right before rendering it in app/markdown/lib/parser/marked/marked.js
line 98.
message.html = _marked(unescapeHTML(message.html), {
gfm,
tables,
breaks,
pedantic,
smartLists,
smartypants,
renderer,
highlight,
});
const window = getGlobalWindow();
const DomPurify = createDOMPurify(window);
message.html = DomPurify.sanitize(message.html, { ADD_ATTR: ['target'] });
Due to the unscape, the user will be able to inject custom HTML elements. Since DomPurify.sanitize
will only sanitize XSS relevant elements and properties, the malicious HTML with the CSS injection will be set into the user’s message.
To avoid the style injection, but still allow the usage of custom tags, DomPurify.sanitize could be configured to also remove style elements and attributes. Another way to mitigate the issue would be to not unescape the html before rendering it with ’marked’ to therefore prohibit the user to use custom HTML in their messages.
An attacker can block the user from certain functionalities as well as render the chat window unusable (e.g. with a rotation of the complete html body) after the user enters a channel. Another impact of the issue is the authenticity and integrity of messages. Since an adversary will be able to manipulate or hide arbitrary user messages, the authenticity and integrity is not given anymore. These attack vectors are stored in messages, which will make them available for every new user entering the channel.
Fixed in 5.0>