Capítulo 84 de 116

Chapter 84: experimental_taintUniqueValue

Core Idea

experimental_taintUniqueValue(message, lifetime, value) is taintObjectReference's sibling for primitive values (strings, numbers) — flags a specific sensitive value (an API key, a session token) so React throws if that exact value is ever serialized across the Server→Client boundary.

Key Concepts

  • For primitives, not objects: since primitives don't have a reference identity the way objects do, this function needs a lifetime argument (an object whose garbage-collected lifetime the taint is tied to) so React knows how long to keep watching for that value.
  • lifetime argument: typically the object the sensitive value was extracted from (e.g. the config/env object holding a secret) — once that object is garbage collected, the taint on the derived primitive value is released too, preventing an unbounded internal tracking list.
  • Same throw-on-crossing behavior as taintObjectReference: if the tainted value is ever passed into something destined for client serialization, React throws with the given message instead of silently including the secret in the client bundle/payload.
  • Typical use case: tainting a raw API key or session secret immediately after reading it from environment/config, so any later code path that accidentally forwards that exact string value to a Client Component fails loudly instead of leaking it.

Code Examples

const apiKey = process.env.SECRET_API_KEY;
experimental_taintUniqueValue(
  'Do not pass SECRET_API_KEY to the client.',
  process.env, // lifetime: taint released when this object is GC'd
  apiKey
);
  • What it demonstrates: tainting a specific secret string value, tied to the lifetime of the process.env object it came from.

Key Takeaways

  1. Use this for primitive secrets (tokens, keys); use taintObjectReference (Ch 83) for whole sensitive objects.
  2. The lifetime argument exists purely for garbage-collection bookkeeping — pick an object whose lifetime naturally matches how long the taint should remain active.
  3. Like its sibling, this is a defense-in-depth backstop, not a substitute for deliberately controlling what data crosses the Server/Client boundary in the first place.

Connects To

  • Ch 83 (experimental_taintObjectReference): the object-reference version of this same protection mechanism.
  • Ch 110 (Server Components): the Server/Client boundary both taint functions guard.