Valtik Studios
Back to blog
Clerkhigh2026-04-1510 min

Clerk Auth: The unsafe_metadata Footgun

Clerk's unsafe_metadata field is client-writable by design. If your application security model reads role assignments from metadata without server-side validation, any authenticated user can escalate to admin. A practical penetration testing guide to finding and fixing this privilege escalation vulnerability.

What is unsafe_metadata?

Clerk provides three metadata fields on every user object:

  • publicMetadata. server-writable only, visible to everyone
  • privateMetadata. server-writable only, visible only server-side
  • unsafeMetadata. client-writable, visible to the user

The name literally warns you. But developers still store role assignments, feature flags, and subscription tiers in unsafeMetadata because it's the only field they can write to from the frontend without a backend.

The escalation chain

  1. Attacker signs up for a free account
  2. Opens browser DevTools, finds the Clerk session token
  3. Sends: PATCH /v1/me { "unsafe_metadata": { "role": "admin", "plan": "enterprise" } }
  4. The app reads user.unsafeMetadata.role and grants admin access

This works because Clerk's API intentionally allows the client to write to unsafeMetadata. It's not a bug. it's a design choice that becomes a vulnerability when the app trusts the field for authorization decisions.

Real-world patterns we've seen

  • SaaS apps storing { plan: "free" | "pro" | "enterprise" } in unsafeMetadata
  • Admin dashboards checking unsafeMetadata.role === "admin" for access control
  • Feature flags gated by unsafeMetadata.features array

How we detect this

Our scanner inspects the Clerk publishable key in the client bundle, then:

  1. Creates a test account via the Clerk signup flow
  2. Reads the user object to see what metadata fields exist
  3. Attempts to PATCH unsafeMetadata with escalated values
  4. Checks if the app UI changes in response

Defense

  • Never use unsafeMetadata for authorization decisions
  • Store roles in publicMetadata (set server-side via Clerk Backend API)
  • Validate permissions server-side against publicMetadata, not unsafeMetadata
  • Use Clerk's RBAC features (Organizations + Roles) instead of custom metadata
clerkauthmetadataprivilege escalationpenetration testingapplication securityvulnerability assessmentresearch

Want us to check your Clerk setup?

Our scanner detects this exact misconfiguration. plus dozens more across 38 platforms. Free website check available, no commitment required.