Vulnerability: wire-webapp is the web application interface for the wire messaging service. Insufficient escaping in markdown “code highlighting” in the wire-webapp resulted in the possibility of injecting and executing arbitrary HTML code and thus also JavaScript. If a user receives and views such a malicious message, arbitrary code is injected and executed in the context of the victim. This allows the attacker to fully control the user account. Wire-desktop clients that are connected to a vulnerable wire-webapp version are also vulnerable to this attack. The issue has been fixed in wire-webapp 2022-03-30-production.0 and is already deployed on all Wire managed services. On-premise instances of wire-webapp need to be updated to docker tag 2022-03-30-production.0-v0.29.2-0-d144552 or wire-server 2022-03-30 (chart/4.8.0), so that their applications are no longer affected. There are no known workarounds for this issue. ### Patches * The issue has been fixed in wire-webapp **2022-03-30-production.0** and is already deployed on all Wire managed services. * On-premise instances of wire-webapp need to be updated to docker tag **2022-03-30-production.0-v0.29.2-0-d144552** or wire-server **2022-03-30 (chart/4.8.0)**, so that their applications are no longer affected. ### Workarounds * No workarounds known ### For more information If you have any questions or comments about this advisory feel free to email us at [vulnerability-report@wire.com](mailto:vulnerability-report@wire.com) ### Credits We thank [Posix](https://twitter.com/po6ix) for reporting this vulnerability
Vulnerability ID: CVE-2022-24799
CWE: CWE-79
Severity score: 2.9
Project: https://github.com/wireapp/wire-webapp
Published: 2022-04-20
File: src/script/util/messageRenderer.ts
Commit message: fix: Improve message rendering (#12748)
Commit author: Thomas Belin

Vulnerable version (before fix):
 export const renderMessage = (message: string, selfId: QualifiedId | null, menti       if (containsMentions) {         // disable code highlighting if there is a mention in there         // highlighting will be wrong anyway because this is not valid code         return code;       }       return hljs.highlightAuto(code).value;     }, export const renderMessage = (message: string, selfId: QualifiedId | null, menti     const cleanString = (hashedString: string) =>       escape(         Object.entries(mentionTexts).reduce(           (text, [mentionHash, mention]) => text.replace(mentionHash, mention.text),           hashedString,         ),       ); export const renderMessage = (message: string, selfId: QualifiedId | null, menti   const parsedText = Object.keys(mentionTexts).reduce((text, mentionHash) => {     const mentionMarkup = renderMention(mentionTexts[mentionHash]);      return text.replace(mentionHash, mentionMarkup);   }, mentionlessText);   return parsedText; };

Fixed version (after fix):
 export const renderMessage = (message: string, selfId: QualifiedId | null, menti       if (containsMentions) {         // disable code highlighting if there is a mention in there         // highlighting will be wrong anyway because this is not valid code         return escape(code);       }       return hljs.highlightAuto(code).value;     }, export const renderMessage = (message: string, selfId: QualifiedId | null, menti     const cleanString = (hashedString: string) =>       escape(         Object.entries(mentionTexts).reduce(           (text, [mentionHash, mention]) => text.replace(mentionHash, () => mention.text),           hashedString,         ),       ); export const renderMessage = (message: string, selfId: QualifiedId | null, menti   const parsedText = Object.keys(mentionTexts).reduce((text, mentionHash) => {     const mentionMarkup = renderMention(mentionTexts[mentionHash]);      return text.replace(mentionHash, () => mentionMarkup);   }, mentionlessText);   return parsedText; };

Patch:
patch: @@ -138,7 +138,7 @@ export const renderMessage = (message: string, selfId: QualifiedId | null, menti
       if (containsMentions) {
         // disable code highlighting if there is a mention in there
         // highlighting will be wrong anyway because this is not valid code
-        return code;
+        return escape(code);
       }
       return hljs.highlightAuto(code).value;
     },
@@ -148,7 +148,7 @@ export const renderMessage = (message: string, selfId: QualifiedId | null, menti
     const cleanString = (hashedString: string) =>
       escape(
         Object.entries(mentionTexts).reduce(
-          (text, [mentionHash, mention]) => text.replace(mentionHash, mention.text),
+          (text, [mentionHash, mention]) => text.replace(mentionHash, () => mention.text),
           hashedString,
         ),
       );
@@ -214,7 +214,7 @@ export const renderMessage = (message: string, selfId: QualifiedId | null, menti
   const parsedText = Object.keys(mentionTexts).reduce((text, mentionHash) => {
     const mentionMarkup = renderMention(mentionTexts[mentionHash]);
 
-    return text.replace(mentionHash, mentionMarkup);
+    return text.replace(mentionHash, () => mentionMarkup);
   }, mentionlessText);
   return parsedText;
 };
path: src/script/util/messageRenderer.ts