Next.js Server Actions security
Every Server Action is a public endpoint
A function marked "use server" can be called by anyone with a POST request, whether or not your UI ever shows the button. Hiding it behind an admin page protects nothing. Paste a Next.js repo and Wyro lists every Server Action and route handler that reaches your database without checking who is calling.
Free for public repositories. No account and nothing installed. Lovable, Bolt and v0 projects work once they are synced to GitHub.
How to secure them
Authenticate inside every action that touches dataWyro checks this
The check belongs in the action, not in the page that renders the form:
"use server"; export async function deletePost(id: string) { const session = await auth(); if (!session) throw new Error("Unauthorized"); await db.delete(posts).where(and(eq(posts.id, id), eq(posts.authorId, session.user.id))); }Wyro reads Server Actions as entry points and reports any that reach a table with no authentication on the way (
auth-before-data).Authorize the row, not just the userWyro checks this
if (!session)stops strangers. It does not stop a signed-in user deleting someone else's post by passing its id. Put the owner in thewhereclause, as above. Wyro marks actions where any signed-in user reaches the data (authenticated-no-authorization).Validate the argumentsWyro checks this
Arguments arrive from the network, typed or not. Parse them with zod before use. TypeScript types are erased at runtime and check nothing.
Middleware is not enough on its own
A
matcherthat skips a path, or a refactor that moves an action, silently removes the check. Keep authentication in the action or in a data-layer function every action calls, so the guard travels with the code.Route handlers need the same careWyro checks this
app/api/**/route.tsexports are public too. Wyro checks them with the same rules, along with Supabase calls made through a user-scoped or service-role client.Rate limit the expensive onesWyro checks this
Sign-up, invites, email sending and anything that calls a paid API. Unlimited, each is a way to run up your bill or spam your users.
Keep it that way
A check run once goes stale the next time an agent adds a route. Sign in, press Watch this repo on its report, and Wyro emails you the day a push adds a new finding. Free.
Questions
Are Next.js Server Actions secure by default?
They get some protection by default: an unguessable action ID and an Origin check against CSRF. Neither checks who the caller is. Any logged-out visitor can still invoke an action, so authentication and authorization must be written inside it.
How does Wyro find Server Actions?
It reads every file and function marked "use server", follows the calls into your data layer, and records which tables each action reads or writes and whether an auth check sits on the path.
Does it run on private repositories?
The free web check reads public GitHub repositories. For private code, run npx wyro-check locally or in CI; the source never leaves your machine.