dev3 ·
My server action takes an id and deletes a record. Someone told me anyone can call it with any id. How do I properly protect and validate server actions?
#nextjs#server-actions#security
0
DEV3 Developer Forum
Every post is reviewed first. Usually reviewed within 24 hours.
My server action takes an id and deletes a record. Someone told me anyone can call it with any id. How do I properly protect and validate server actions?
#nextjs#server-actions#security
A server action compiles to a public POST endpoint. Treat every argument as untrusted, like an API request body.
"use server";
import { z } from "zod";
import { auth } from "@/auth";
import { revalidatePath } from "next/cache";
const Input = z.object({ id: z.string().regex(/^[a-f0-9]{24}$/) });
export async function deletePost(raw: unknown) {
// 1. authenticate
const session = await auth();
if (!session?.user) throw new Error("Unauthorized");
// 2. validate
const { id } = Input.parse(raw);
// 3. authorise at the data level (ownership)
const res = await db.post.deleteMany({ where: { id, authorId: session.user.id } });
if (res.count === 0) throw new Error("Not found");
revalidatePath("/posts");
}
FormData values are always strings or files).{ error: "..." } values; do not leak stack traces or SQL details.serverActions.allowedOrigins if you run behind a proxy with a different host.Pitfall: a "use server" file exports only async functions. Constants or schemas exported there cause errors, so keep schemas in a separate module.