What crosses the boundary: a row versus a DTO
The card looks identical either way, which is exactly why this leak is easy to miss: the screen shows a name, while the payload carried the password hash, reset token and internal notes to every visitor. The DTO is also a third of the size.
A Server Function ("use server") is a public HTTP endpoint that anyone can call with any arguments, so each one must validate its input, check who is calling and whether they may touch this record, and return only what the UI needs; and Server Components must pass Client Components only the fields they need, with the taint APIs as an experimental safety net.
Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.
Ready for more? This phase has 5 hands-on exercises with automatic checks.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Write a deleteComment(commentId) Server Function that is safe to expose.
Write a narrowly typed Client Component AuthorBadge and the Server Component code that passes it data from a user row.
List what you'd check when auditing a file that starts with "use server".
Explain it without notes
Why must every Server Function check authentication and authorisation itself?
What are the four steps every Server Function should take, and why that order?
How can a Server Component leak private data, and what is the recommended fix?
What do experimental_taintObjectReference and experimental_taintUniqueValue do, and what are their limits?
Preview
Console
Nothing logged yet.Expected console output
sent with the whole row: id, name, avatar, email, passwordHash, resetToken, isAdmin, internalNotes
sent with the DTO: id, name, avatar
bytes: 189 vs 51