Skip to content
Back to posts

June 14, 2026

Leak-proof components

In a Server Components world, the boundary between server and client is a single prop away. Pass the wrong object across it and you serialize secrets straight into the HTML. On a social app the obvious danger is the session object, which often carries an auth token right next to the harmless display name.

The accidental leak

async function ProfileHeader() {
  const session = await getSession()

  // FollowButton is a Client Component
  return <FollowButton session={session} />
}

The whole session object, including session.token, gets serialized and shipped to the browser so a client component can read one field. The token is now sitting in the page payload for anyone to grab.

The fix

React’s experimental taint APIs mark a value as server only. If anything tries to send it to the client, React throws instead of silently serializing it.

import { experimental_taintUniqueValue } from 'react'

async function ProfileHeader() {
  const session = await getSession()

  experimental_taintUniqueValue(
    'Do not pass the session token to the client.',
    session,
    session.token,
  )

  // Pass only what the client actually needs
  return <FollowButton viewerId={session.userId} />
}

Tainting turns a quiet data leak into a loud build time error. The safest secret is the one the framework refuses to let you ship.