Home / Companies / WorkOS / Blog / Post Details
Content Deep Dive

Microsoft Titan JWT bug: Never use upn as a local username

Blog post from WorkOS

Post Details
Company
Date Published
Author
Maria Paktiti
Word Count
2,195
Company Posts That Month
36
Language
English
Hacker News Points
-
Post removed?
No
Summary

A 16-year-old security researcher discovered that Microsoft’s internal Titan analytics service accepted unsigned JWTs and used the mutable `upn` claim to look up local user accounts, allowing a token with `upn: admin` to resolve to Titan’s privileged administrator account and execute SQL queries. The researcher reported the issue promptly, Microsoft restricted the endpoint within days, and a $5,000 bounty was awarded; the reported exposure was assessed through metadata and limited samples rather than by accessing customer data or PII. The incident combined two authentication design failures: Titan processed attacker-modified JWT claims without verifying a signature, including accepting `alg: none`, and it treated an external human-readable identifier as a local authorization key. The account argues that signature validation alone would not fully solve the identity-linking problem because UPNs and email addresses can change, be reassigned, or represent guests from other tenants. It recommends verifying tokens with pinned algorithms, issuer-owned keys, audience, expiration, and tenant restrictions before resolving users exclusively through stable issuer-and-subject identifiers such as `iss + sub` or Entra’s `oid` with tenant context, while retaining email and UPN only as display or audit data. It also warns that detailed authentication errors can enable automated probing and advises returning uniform unauthorized responses externally while logging specific failures internally.

Trends Found in this Post

No tracked trend matches for this post yet.

Use This Data

Use this post, company, and trend context to find content marketing opportunities, perform competitive analysis, or address product feature gaps via the Plushcap MCP server or the Plushcap API.