Loading HuntDB...

Persistent CSS injection with ’marked’ markdown parser in Rocket.Chat

High
R
Rocket.Chat
Submitted None

Team Summary

Official summary from Rocket.Chat

**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. ## Releases Affected: * 4.1.0 with 'marked' parser ## Steps To Reproduce (from initial installation to vulnerability): (Add details for how we can reproduce the issue) 1. Setup a new installation of Rocket.Chat 2. Enable the 'marked' parser in the admin settings under 'Message' > 'Markdown' > 'Markdown Parser' 3. Create a second user account with username `usertest` and a channel containing both accounts 4 . Send some messages between both accounts 5. Send ```html <div style="position: fixed; top: 6px; right: 0px; height: 50px; width: 400px; background: rgb(255,0,0); z-index: 3">foobar</div> ``` This should block the top right channel settings with a red box. 6. Send ```html 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). ## Supporting Material/References: ### Root Cause 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. ```js 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. ## Suggested mitigation 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. ## Impact 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. ## Fix Fixed in 5.0>

Reported by danieljpp

Report Details

Additional information and metadata

State

Closed

Substate

Resolved

Submitted

Weakness

Cross-site Scripting (XSS) - Stored