Engrain by ByteRush

RCT.06.04 Senior· 12 minCore — asked often

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
}
A copied request with a changed idStep 1 of 4

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
    1. The profile form calls updateProfile({ userId: 7, name }) for the signed-in user 7. It works in the UI.
    2. An attacker copies the request from DevTools and changes userId to 8. The function trusts the input.
    3. User 8's profile is overwritten. The UI never offered this, but the endpoint accepted it.
    4. 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?

    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.”

    Stays on your device. Nothing is uploaded.
    Follow-up Are server actions secure by default? What must you do?
    No. Authenticate from the session, validate inputs, authorize per record, limit writes to allowed fields, and rate-limit sensitive actions.
    Follow-up Why does importing server-only help?
    It makes the build fail if a server module, for example one holding API keys, is imported into client code.
    Follow-up How can a closure leak a secret?
    An inline Server Function that captures a variable from the component may send that value to the client so it can be passed back; frameworks encrypt it, but keep secrets out of closures anyway.

    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 name and email are saved, never role or other fields.
    Your solution
    Ctrl/⌘ + Enter

    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
    Props to client components are sent to the browser. Inline Server Functions may serialize captured variables to the client; frameworks encrypt these, but do not capture secrets.
    Import 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

    CVE-2025-55182 (3 Dec 2025) was an unauthenticated remote code execution flaw in React Server Components, CVSS 10.0, fixed in react-server-dom-* 19.0.1, 19.1.2 and 19.2.1; apps supporting RSC were exposed even without their own Server Functions. Follow-up advisories fixed denial-of-service and source-code-exposure bugs Source: React: Critical security vulnerability in React Server Components.
    Subscribe to your framework’s advisories and update quickly.

    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?