Skip to content

Security: Neynar API key exposed to the client via NEXT_PUBLIC_NEYNAR_API_KEY #751

Description

@hellno

Problem

The Neynar API key is exposed to the browser. NEXT_PUBLIC_NEYNAR_API_KEY is referenced in client code (src/common/helpers/farcaster.ts:541, as an x-api-key header), so Next.js inlines it into the client JS bundle — anyone can read it from the deployed app and burn our Neynar quota (which is already over its CU limit).

Scope

  • Actual leak: src/common/helpers/farcaster.ts:541 (client x-api-key). This is what puts the key in the browser bundle.
  • Convention: ~22 app/api/* route handlers also read process.env.NEXT_PUBLIC_NEYNAR_API_KEY. Read server-side they don't leak on their own, but the NEXT_PUBLIC_ naming keeps the value in the public env and invites client use.
  • The Supabase edge functions already do this correctly — they use a server-only NEYNAR_API_KEY (Deno env). There is currently no server-only NEYNAR_API_KEY in the Vercel/Next environment.

Pre-existing — every /api route predates the Hypersnap work. Flagged by the review on #734 and scoped out, since fixing it touches ~23 files + an env change + a key rotation.

Remediation

  1. Rotate the Neynar API key (the current one has been public in the client bundle).
  2. Add the new key to Vercel as a server-only NEYNAR_API_KEY (no NEXT_PUBLIC_ prefix).
  3. Migrate all app/api/* routes: process.env.NEXT_PUBLIC_NEYNAR_API_KEYprocess.env.NEYNAR_API_KEY.
  4. Move the client call at src/common/helpers/farcaster.ts:541 behind a server route, so the key never reaches the browser. This is the one that actually leaks — steps 1–3 don't help until this is done.
  5. Remove NEXT_PUBLIC_NEYNAR_API_KEY from all environments once nothing references it.
  6. (Optional) Add a build/lint check that fails on NEXT_PUBLIC_*_(API_KEY|SECRET|TOKEN) patterns.

Acceptance criteria

  • No NEXT_PUBLIC_NEYNAR_API_KEY references remain in client or server code.
  • The Neynar key is absent from the built client bundle (grep .next output).
  • All /api routes + the former client call work with the server-only NEYNAR_API_KEY.

Files

  • src/common/helpers/farcaster.ts:541 (the leak)
  • app/api/**/route.ts (~22 files)
  • Vercel env config

Refs #734 (review that surfaced this), #715.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions