CVE-2024-5208: Insufficient Information (NVD-CWE-noinfo)
value: An uncontrolled resource consumption vulnerability exists in the `upload-link` endpoint of mintplex-labs/anything-llm. This vulnerability allows attackers to cause a denial of service (DOS) by shutting down the server through sending invalid upload requests. Specifically, the server can be made to shut down by sending an empty body with a 'Content-Length: 0' header or by sending a body with arbitrary content, such as 'asdasdasd', with a 'Content-Length: 9' header. The vulnerability is reproducible by users with at least a 'Manager' role, sending a crafted request to any workspace. This issue indicates that a previous fix was not effective in mitigating the vulnerability.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
Published: 2024-06-19T06:15Z
Repository: https://github.com/mintplex-labs/anything-llm
Language: JavaScript
Files changed: server/endpoints/workspaces.js
Commit date: 2024-05-22 11:34:15 -0500
Commit message: patch endpoint without exception handler

Diff: diff --git a/server/endpoints/workspaces.js b/server/endpoints/workspaces.js
index 81cbd6154..615716597 100644
--- a/server/endpoints/workspaces.js
+++ b/server/endpoints/workspaces.js
@@ -109,81 +109,92 @@ function workspaceEndpoints(app) {
       validatedRequest,
       flexUserRoleValid([ROLES.admin, ROLES.manager]),
       handleFileUpload,
     ],
     async function (request, response) {
-      const Collector = new CollectorApi();
-      const { originalname } = request.file;
-      const processingOnline = await Collector.online();
+      try {
+        const Collector = new CollectorApi();
+        const { originalname } = request.file;
+        const processingOnline = await Collector.online();
+
+        if (!processingOnline) {
+          response
+            .status(500)
+            .json({
+              success: false,
+              error: `Document processing API is not online. Document ${originalname} will not be processed automatically.`,
+            })
+            .end();
+          return;
+        }
 
-      if (!processingOnline) {
-        response
-          .status(500)
-          .json({
-            success: false,
-            error: `Document processing API is not online. Document ${originalname} will not be processed automatically.`,
-          })
-          .end();
-        return;
-      }
+        const { success, reason } =
+          await Collector.processDocument(originalname);
+        if (!success) {
+          response.status(500).json({ success: false, error: reason }).end();
+          return;
+        }
 
-      const { success, reason } = await Collector.processDocument(originalname);
-      if (!success) {
-        response.status(500).json({ success: false, error: reason }).end();
-        return;
+        Collector.log(
+          `Document ${originalname} uploaded processed and successfully. It is now available in documents.`
+        );
+        await Telemetry.sendTelemetry("document_uploaded");
+        await EventLogs.logEvent(
+          "document_uploaded",
+          {
+            documentName: originalname,
+          },
+          response.locals?.user?.id
+        );
+        response.status(200).json({ success: true, error: null });
+      } catch (e) {
+        console.log(e.message, e);
+        response.sendStatus(500).end();
       }
-
-      Collector.log(
-        `Document ${originalname} uploaded processed and successfully. It is now available in documents.`
-      );
-      await Telemetry.sendTelemetry("document_uploaded");
-      await EventLogs.logEvent(
-        "document_uploaded",
-        {
-          documentName: originalname,
-        },
-        response.locals?.user?.id
-      );
-      response.status(200).json({ success: true, error: null });
     }
   );
 
   app.post(
     "/workspace/:slug/upload-link",
     [validatedRequest, flexUserRoleValid([ROLES.admin, ROLES.manager])],
     async (request, response) => {
-      const Collector = new CollectorApi();
-      const { link = "" } = reqBody(request);
-      const processingOnline = await Collector.online();
+      try {
+        const Collector = new CollectorApi();
+        const { link = "" } = reqBody(request);
+        const processingOnline = await Collector.online();
+
+        if (!processingOnline) {
+          response
+            .status(500)
+            .json({
+              success: false,
+              error: `Document processing API is not online. Link ${link} will not be processed automatically.`,
+            })
+            .end();
+          return;
+        }
 
-      if (!processingOnline) {
-        response
-          .status(500)
-          .json({
-            success: false,
-            error: `Document processing API is not online. Link ${link} will not be processed automatically.`,
-          })
-          .end();
-        return;
-      }
+        const { success, reason } = await Collector.processLink(link);
+        if (!success) {
+          response.status(500).json({ success: false, error: reason }).end();
+          return;
+        }
 
-      const { success, reason } = await Collector.processLink(link);
-      if (!success) {
-        response.status(500).json({ success: false, error: reason }).end();
-        return;
+        Collector.log(
+          `Link ${link} uploaded processed and successfully. It is now available in documents.`
+        );
+        await Telemetry.sendTelemetry("link_uploaded");
+        await EventLogs.logEvent(
+          "link_uploaded",
+          { link },
+          response.locals?.user?.id
+        );
+        response.status(200).json({ success: true, error: null });
+      } catch (e) {
+        console.log(e.message, e);
+        response.sendStatus(500).end();
       }
-
-      Collector.log(
-        `Link ${link} uploaded processed and successfully. It is now available in documents.`
-      );
-      await Telemetry.sendTelemetry("link_uploaded");
-      await EventLogs.logEvent(
-        "link_uploaded",
-        { link },
-        response.locals?.user?.id
-      );
-      response.status(200).json({ success: true, error: null });
     }
   );
 
   app.post(
     "/workspace/:slug/update-embeddings",

Vulnerable code:       const Collector = new CollectorApi();
      const { originalname } = request.file;
      const processingOnline = await Collector.online();
      if (!processingOnline) {
        response
          .status(500)
          .json({
            success: false,
            error: `Document processing API is not online. Document ${originalname} will not be processed automatically.`,
          })
          .end();
        return;
      }
      const { success, reason } = await Collector.processDocument(originalname);
      if (!success) {
        response.status(500).json({ success: false, error: reason }).end();
        return;

      Collector.log(
        `Document ${originalname} uploaded processed and successfully. It is now available in documents.`
      );
      await Telemetry.sendTelemetry("document_uploaded");
      await EventLogs.logEvent(
        "document_uploaded",
        {
          documentName: originalname,
        },
        response.locals?.user?.id
      );
      response.status(200).json({ success: true, error: null });
      const Collector = new CollectorApi();
      const { link = "" } = reqBody(request);
      const processingOnline = await Collector.online();
      if (!processingOnline) {
        response
          .status(500)
          .json({
            success: false,
            error: `Document processing API is not online. Link ${link} will not be processed automatically.`,
          })
          .end();
        return;
      }
      const { success, reason } = await Collector.processLink(link);
      if (!success) {
        response.status(500).json({ success: false, error: reason }).end();
        return;

      Collector.log(
        `Link ${link} uploaded processed and successfully. It is now available in documents.`
      );
      await Telemetry.sendTelemetry("link_uploaded");
      await EventLogs.logEvent(
        "link_uploaded",
        { link },
        response.locals?.user?.id
      );
      response.status(200).json({ success: true, error: null });
Fixed code:       try {
        const Collector = new CollectorApi();
        const { originalname } = request.file;
        const processingOnline = await Collector.online();

        if (!processingOnline) {
          response
            .status(500)
            .json({
              success: false,
              error: `Document processing API is not online. Document ${originalname} will not be processed automatically.`,
            })
            .end();
          return;
        }
        const { success, reason } =
          await Collector.processDocument(originalname);
        if (!success) {
          response.status(500).json({ success: false, error: reason }).end();
          return;
        }
        Collector.log(
          `Document ${originalname} uploaded processed and successfully. It is now available in documents.`
        );
        await Telemetry.sendTelemetry("document_uploaded");
        await EventLogs.logEvent(
          "document_uploaded",
          {
            documentName: originalname,
          },
          response.locals?.user?.id
        );
        response.status(200).json({ success: true, error: null });
      } catch (e) {
        console.log(e.message, e);
        response.sendStatus(500).end();
      try {
        const Collector = new CollectorApi();
        const { link = "" } = reqBody(request);
        const processingOnline = await Collector.online();

        if (!processingOnline) {
          response
            .status(500)
            .json({
              success: false,
              error: `Document processing API is not online. Link ${link} will not be processed automatically.`,
            })
            .end();
          return;
        }
        const { success, reason } = await Collector.processLink(link);
        if (!success) {
          response.status(500).json({ success: false, error: reason }).end();
          return;
        }
        Collector.log(
          `Link ${link} uploaded processed and successfully. It is now available in documents.`
        );
        await Telemetry.sendTelemetry("link_uploaded");
        await EventLogs.logEvent(
          "link_uploaded",
          { link },
          response.locals?.user?.id
        );
        response.status(200).json({ success: true, error: null });
      } catch (e) {
        console.log(e.message, e);
        response.sendStatus(500).end();