Today I learned that any time you have a “use server” function that is in the import tree of a given route, it is exposed as an endpoint even if you don’t use it. The main point is that you should know you are creating endpoints when you make server actions and you need to treat them as such — that is, with authentication and security top of mind.
Here’s a super simple example. I created a next app and made a server component that renders a client component called ClientForm. ClientForm renders a form with a server action that calls a function in server-utils, a “use server” module.
import ClientForm from "../components/ClientForm";
export default function Home() {
return (
<main>
<h1>Home</h1>
<ClientForm />
</main>
);
}
// ClientForm.tsx
"use client";
import { getUserData } from "@/app/server-utils";
const ClientForm = () => {
return (
<form action={getUserData}>
<input type="text" placeholder="Name" />
<button type="submit">Submit</button>
</form>
);
};
export default ClientForm;
// server-utils.ts
"use server";
export async function getUserData() {
return { name: "John Doe" };
}
export async function getUserSSN() {
return { ssn: "123-45-6789" };
}
Any exported functions from this “use server” file are endpoints that are exposed to the world — even getUserSSN, which we don’t use in the route or elsewhere.
I pushed this app to Vercel, visited it in prod, and submitted the form. This showed me the server action in the network tab, which I could copy to a curl request and then run again in the terminal.
I could also look at the Sources tab of dev tools, which let me see all the endpoints identified with IDs — in this case, two of them: 64356982 and 51a9fcfd.
I can then run the same curl command with the other endpoint which I never explicitly called and perhaps didn’t mean to expose. As you see in this screenshot from my terminal, I hit the endpoint and got back its data.
In case it's hard to see, here it is larger:
The takeaway is to treat your “use server” function as endpoints. For a production site, be very careful with them. For example, put them in a special folder and protect it with rules that require code-review by code-owners — people well versed in the security requirements of your endpoints.
Here's the sandbox site on vercel.