CVE-2024-0435: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: User can send a chat that contains an XSS opportunity that will then run when the chat is sent and on subsequent page loads.

Given the minimum requirement for a user to send a chat is to be given access to a workspace via an admin the risk is low. Additionally, the location in which the XSS renders is only limited to the user who submits the XSS. 

Ultimately, this attack is limited to the user attacking themselves. There is no anonymous chat submission unless the user does not take the minimum steps required to protect their instance.
CWE description: The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
Published: 2024-02-26T16:27Z
Repository: https://github.com/mintplex-labs/anything-llm
Language: JSON
Files changed: frontend/package.json, frontend/src/components/WorkspaceChat/ChatContainer/ChatHistory/HistoricalMessage/index.jsx, frontend/yarn.lock
Commit date: 2024-01-11 09:57:59 -0800
Commit message: Patch minor XSS opportunity where user can self-XSS themselves.  (#574)

Patch minor XSS opportunity where user can self-XSS themselvess. There is not real vuln here as any instance is not public facing
Diff: diff --git a/frontend/package.json b/frontend/package.json
index ff269895..86e552ab 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -14,10 +14,11 @@
     "@esbuild-plugins/node-globals-polyfill": "^0.1.1",
     "@metamask/jazzicon": "^2.0.0",
     "@microsoft/fetch-event-source": "^2.0.1",
     "@phosphor-icons/react": "^2.0.13",
     "buffer": "^6.0.3",
+    "dompurify": "^3.0.8",
     "he": "^1.2.0",
     "highlight.js": "^11.9.0",
     "lodash.debounce": "^4.0.8",
     "markdown-it": "^13.0.1",
     "pluralize": "^8.0.0",
diff --git a/frontend/src/components/WorkspaceChat/ChatContainer/ChatHistory/HistoricalMessage/index.jsx b/frontend/src/components/WorkspaceChat/ChatContainer/ChatHistory/HistoricalMessage/index.jsx
index f0605a37..4637b1cd 100644
--- a/frontend/src/components/WorkspaceChat/ChatContainer/ChatHistory/HistoricalMessage/index.jsx
+++ b/frontend/src/components/WorkspaceChat/ChatContainer/ChatHistory/HistoricalMessage/index.jsx
@@ -4,10 +4,12 @@ import Jazzicon from "../../../../UserIcon";
 import renderMarkdown from "@/utils/chat/markdown";
 import { userFromStorage } from "@/utils/request";
 import Citations from "../Citation";
 import { AI_BACKGROUND_COLOR, USER_BACKGROUND_COLOR } from "@/utils/constants";
 import { v4 } from "uuid";
+import createDOMPurify from "dompurify";
+const DOMPurify = createDOMPurify(window);
 
 const HistoricalMessage = forwardRef(
   (
     { uuid = v4(), message, role, workspace, sources = [], error = false },
     ref
@@ -43,11 +45,13 @@ const HistoricalMessage = forwardRef(
                 respond to message.
               </span>
             ) : (
               <span
                 className={`whitespace-pre-line text-white font-normal text-sm md:text-sm flex flex-col gap-y-1 mt-2`}
-                dangerouslySetInnerHTML={{ __html: renderMarkdown(message) }}
+                dangerouslySetInnerHTML={{
+                  __html: DOMPurify.sanitize(renderMarkdown(message)),
+                }}
               />
             )}
           </div>
           {role === "assistant" && <Citations sources={sources} />}
         </div>
diff --git a/frontend/yarn.lock b/frontend/yarn.lock
index e7b223df..c9181f15 100644
--- a/frontend/yarn.lock
+++ b/frontend/yarn.lock
@@ -1019,10 +1019,15 @@ doctrine@^3.0.0:
   resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961"
   integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==
   dependencies:
     esutils "^2.0.2"
 
+dompurify@^3.0.8:
+  version "3.0.8"
+  resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.0.8.tgz#e0021ab1b09184bc8af7e35c7dd9063f43a8a437"
+  integrity sha512-b7uwreMYL2eZhrSCRC4ahLTeZcPZxSmYfmcQGXGkXiZSNW1X85v+SDM5KsWcpivIiUBH47Ji7NtyUdpLeF5JZQ==
+
 electron-to-chromium@^1.4.535:
   version "1.4.576"
   resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.576.tgz#0c6940fdc0d60f7e34bd742b29d8fa847c9294d1"
   integrity sha512-yXsZyXJfAqzWk1WKryr0Wl0MN2D47xodPvEEwlVePBnhU5E7raevLQR+E6b9JAD3GfL/7MbAL9ZtWQQPcLx7wA==
 

Vulnerable code:                 dangerouslySetInnerHTML={{ __html: renderMarkdown(message) }}
Fixed code:     "dompurify": "^3.0.8",
import createDOMPurify from "dompurify";
const DOMPurify = createDOMPurify(window);
                dangerouslySetInnerHTML={{
                  __html: DOMPurify.sanitize(renderMarkdown(message)),
                }}
dompurify@^3.0.8:
  version "3.0.8"
  resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.0.8.tgz#e0021ab1b09184bc8af7e35c7dd9063f43a8a437"
  integrity sha512-b7uwreMYL2eZhrSCRC4ahLTeZcPZxSmYfmcQGXGkXiZSNW1X85v+SDM5KsWcpivIiUBH47Ji7NtyUdpLeF5JZQ==