Server Functions and security: every "use server" is a public endpoint
Server Functions are callable over HTTP by anyone, so validate every input and check authorization inside them, avoid leaking secrets through closures, use the server-only package, and know the December 2025 RSC security advisories.
Comes up in: React, Frontend system design, Web fundamentals
Learn#
Arjun’s profile page calls a Server Function with the user’s id. It only ever sends the signed-in user’s id, so he skipped the permission check. Someone changed the id in a copied request and edited other users’ profiles.
A Server Function, marked with "use server", runs on the server but can be called from the client. Under the hood, the framework turns it into an HTTP endpoint. Anyone can call it with any arguments; your UI is not a security layer. When used as a form action, it is called a Server Action.
So every Server Function needs the same checks as an API route: who is calling, are the arguments valid, and is this user allowed to do this to this record? That last check is authorization:
"use server";
import { z } from "zod";
const Input = z.object({ userId: z.number(), name: z.string().trim().min(1).max(50) });
export async function updateProfile(raw) {
const session = await getSession(); // who is calling?
if (!session) throw new Error("Not signed in");
const input = Input.parse(raw); // never trust the shape
if (input.userId !== session.userId && session.role !== "admin") throw new Error("Forbidden");
await db.user.update(input.userId, { name: input.name }); // only allowed fields
}Network
- POST (server function) userId=7 → 200
State
empty
The profile form calls updateProfile({ userId: 7, name }) for the signed-in user 7. It works in the UI.
Read the steps as text
- The profile form calls updateProfile({ userId: 7, name }) for the signed-in user 7. It works in the UI.
- An attacker copies the request from DevTools and changes userId to 8. The function trusts the input.
- User 8's profile is overwritten. The UI never offered this, but the endpoint accepted it.
- Fixed: the function reads the user from the session, validates the input, and ignores userId and role from the client.
Predict#
Predict first
A Server Function is only imported by an admin-only page. Is it safe without an admin check inside?
Hiding the button hides nothing on the network. The function’s endpoint is reachable directly, so authorization must happen inside the function, every time.
Interview angle#
Say it like this — about 30 seconds
“No, Server Functions are not secure by default. Each one is a public HTTP endpoint that anyone can call with any arguments. Inside every function I read the user from the session rather than from arguments, validate the input with a schema, check that this user may act on this record, and write only allowed fields. I keep secrets in server-only modules and avoid closures that capture sensitive values. And I keep React and the framework patched: December 2025 brought a critical RSC remote code execution advisory.”
Follow-up Are server actions secure by default? What must you do?
Follow-up Why does importing server-only help?
Follow-up How can a closure leak a secret?
Practice#
On your own
Secure a profile-update Server Function: session, validation, authorization and safe writes.
Done when
- No session, invalid input and a forbidden target each throw the right error, in that order.
- Users can update only themselves; admins can update anyone.
- Only
nameandemailare saved, neverroleor other fields.
Remember#
Try to answer each card before you open it. Then add them to your reviews.
Who can call a Server Function?
Anyone who can reach its endpoint, with any arguments.
Where should a Server Function get the user's identity?
From the server session, never from its arguments.
What does the server-only package do?
Fails the build if a server module is imported into client code.
What was CVE-2025-55182?
A critical (CVSS 10.0) unauthenticated remote code execution bug in React Server Components.
Go deeper
Four layers. Stop at the one your interview needs; each ends with a quick check.
The core ideaEvery round
Treat each Server Function like a public API route: authenticate, validate, authorize, then act. Return safe error messages, and log details on the server only (JS.13.02).
Check yourself: What three checks does every Server Function need?
Authentication, input validation and authorization.
How it works underneathSenior rounds
The bundler replaces each Server Function in client code with a reference: an id the client posts to, with serialized arguments. Any client can post to that id Source: React: 'use server'.
Check yourself: Why are Server Functions callable directly?
The bundler gives each one an id and an HTTP endpoint the client posts to.
Edge cases and trapsWhere people slip
server-only in modules with keys and database code.Check yourself: Name two ways secrets can reach the browser in RSC apps.
Passing them as props to client components, and capturing them in inline Server Function closures.
In productionStaff-level answers
Check yourself: Which versions patched CVE-2025-55182?
react-server-dom-* 19.0.1, 19.1.2 and 19.2.1.
Finished the five steps? Mark it, and its cards join your reviews.
Last checked 2026-11-01. Spot a mistake? Use “Report an error” below — fixes are listed on the corrections page.
Interview questions this answers
- Are server actions secure by default? What must you do?