CVE-2024-37162 (published 2024-06-07T15:15Z)

zsa is a library for building typesafe server actions in Next.js. All users are impacted. The zsa application transfers the parse error stack from the server to the client in production build mode. This can potentially reveal sensitive information about the server environment, such as the machine username and directory paths. An attacker could exploit this vulnerability to gain unauthorized access to sensitive server information. This information could be used to plan further attacks or gain a deeper understanding of the server infrastructure. This has been patched on `0.3.3`.


Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/IdoPesok/zsa
commit_details: repo_url: https://github.com/IdoPesok/zsa
author: Ido Pesok
author_date: 2024-06-06 13:38:07-07:00
msg: remove stack from errors
repository: repo_url: https://github.com/IdoPesok/zsa
repo_name: IdoPesok/zsa
repo_language: TypeScript
owner: IdoPesok
file_changes: filename: component.tsx
change_type: ModificationType.ADD
diff: @@ -0,0 +1,17 @@
+"use client"
+
+import IncrementExample from "@/content/docs/examples/introduction/increment-example"
+import { useState } from "react"
+
+export default function RevalidateComponent() {
+  const [open, setOpen] = useState(false)
+  return (
+    <div>
+      {open ? (
+        <IncrementExample />
+      ) : (
+        <button onClick={() => setOpen(true)}>Open</button>
+      )}
+    </div>
+  )
+}

programming_language: JavaScript
filename: page.tsx
change_type: ModificationType.ADD
diff: @@ -0,0 +1,15 @@
+import RevalidateComponent from "./component"
+
+export default async function RevalidatePage() {
+  // sleep for 2 seconds
+  await new Promise((resolve) => setTimeout(resolve, 1000))
+  const randomNumber = Math.floor(Math.random() * 10000)
+
+  return (
+    <div>
+      <h1>Revalidate Page</h1>
+      <p>Random number: {randomNumber}</p>
+      <RevalidateComponent />
+    </div>
+  )
+}

programming_language: TypeScript
filename: actions.ts
change_type: ModificationType.MODIFY
diff: @@ -1,5 +1,6 @@
 "use server"
 
+import { revalidatePath } from "next/cache"
 import z from "zod"
 import { createServerAction } from "zsa"
 
@@ -11,7 +12,10 @@ export const incrementNumberAction = createServerAction()
   )
   .handler(async ({ input }) => {
     await new Promise((resolve) => setTimeout(resolve, 500))
-    return input.number + 1
+
+    revalidatePath("/revalidate", "page")
+
+    return input.number + 2
   })
 
 export const plainAction = createServerAction().handler(async () => {

programming_language: TypeScript
filename: increment-example.tsx
change_type: ModificationType.MODIFY
diff: @@ -3,6 +3,7 @@
 import { Button } from "@/components/ui/button"
 import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
 import { useState } from "react"
+import { toast } from "sonner"
 import { useServerAction } from "zsa-react"
 import { incrementNumberAction } from "./actions"
 
@@ -31,6 +32,7 @@ export default function IncrementExample() {
               return
             }
 
+            toast("got data" + data)
             setCounter(data)
           }}
         >

programming_language: TypeScript
filename: errors.ts
change_type: ModificationType.MODIFY
diff: @@ -57,7 +57,6 @@ export type TZSAError<TInputSchema extends z.ZodType> = Error &
     | {
         code: Exclude<keyof typeof ERROR_CODES, "INPUT_PARSE_ERROR">
         message?: string
-        stack: string
         data: string
         name: string
         fieldErrors?: undefined
@@ -66,7 +65,6 @@ export type TZSAError<TInputSchema extends z.ZodType> = Error &
       }
     | {
         message?: string
-        stack: string
         code: "INPUT_PARSE_ERROR"
         data: string
         name: string

programming_language: TypeScript
filename: zod-safe-function.ts
change_type: ModificationType.MODIFY
diff: @@ -512,7 +512,6 @@ export class ZodSafeFunction<
       {
         data: stringifyIfNeeded(customError.data),
         name: customError.name,
-        stack: JSON.stringify(customError.stack),
         message: stringifyIfNeeded(customError.message),
         code: customError.code,
         fieldErrors: flattenedErrors?.fieldErrors,

programming_language: TypeScript
filename: openapi.test.tsx
change_type: ModificationType.MODIFY
diff: @@ -165,7 +165,6 @@ describe("openapi", () => {
       const json = await response.json()
       expect(json.code).toBe("INPUT_PARSE_ERROR")
       expect(json.message).toBeDefined()
-      expect(json.stack).not.toBeDefined()
     })
 
     it("should multiply two numbers [POST]", async () => {
@@ -387,7 +386,6 @@ describe("openapi", () => {
       const json = await response.json()
       expect(json.code).toBe("INPUT_PARSE_ERROR")
       expect(json.message).toBeDefined()
-      expect(json.stack).toBeDefined()
       expect(json.name).toBeDefined()
     })
 
@@ -419,7 +417,6 @@ describe("openapi", () => {
       const json = await response.json()
       expect(json.code).toBe("INPUT_PARSE_ERROR")
       expect(json.message).toBeDefined()
-      expect(json.stack).not.toBeDefined()
     })
   })
 

programming_language: TypeScript