mrkeyoor.com_
Wed 30 Sept 20:33 UTC
Tech6 min read

Microsoft Titan's Unsigned JWT Put 17.3T Rows Within Reach

A public Microsoft analytics API trusted the claims inside an unsigned JWT. A researcher says the bypass made 17.3 trillion stored rows technically reachable.

Ten days of AI-assisted probing stopped at a field named upn. The path into Microsoft's internal Titan analytics service opened only when a 16-year-old researcher ignored that label, tried admin, and received the number 1 from an unauthorized SQL query. Behind that tiny response were 17 connected analytics databases containing an estimated 17,333,335,124,315 stored rows that were technically reachable, according to the researcher's coordinated disclosure.

That number needs a boundary around it. The researcher, who publishes as Faav, says he did not dump the databases, access customer data, or touch personally identifiable information beyond bounded samples used to confirm the flaw. The 17.3 trillion figure came from database metadata and likely includes historical, duplicated, and derived records. Microsoft locked down the API four days after the report, then provided a statement thanking Faav for reporting the finding through its bug bounty program.

A public API behind a private front door

Titan's web interface displayed a VPN requirement, but its API lived on a separate, publicly reachable Azure Cloud Services host. An exposed Swagger document listed four routes, including /v2/Query, which accepted raw SQL. Faav's AI system, Antares, found the service on August 25 and recovered 56 table definitions from a 2023 snapshot of Titan's old Superset interface in the Wayback Machine. One routing value, TestData, was enough to start testing the live query endpoint.

A request without an authorization header returned 401 Unauthorized. That response suggested the API had an authentication barrier. Over the next ten days, Antares changed claims in a token and used the resulting errors to work through Titan's checks. A Microsoft tenant value passed one stage, the expected audience passed another, and an allowed application ID reached a user lookup. The token's signature never changed while its contents did. Titan was reading the claims as if they were trustworthy without establishing who had signed them.

Faav then sent a synthetic JSON Web Token with an empty signature. Its header was short:

{"alg": "none", "typ": "JWT"}

The serialized token ended after the second period, in the form base64url(header).base64url(payload).. Titan still processed its tenant, audience, application and user claims. This was more dangerous than an endpoint that simply forgot an authorization check. The service performed several checks, but all of them relied on attacker-controlled text.

The field name that trapped the agent

The remaining obstacle looked mundane. Titan returned User not found for the value placed in the upn claim. In Microsoft Entra, UPN normally means user principal name and commonly resembles an email address. Antares, running Codex and Claude on the lead, kept generating email-shaped identities, service aliases and placeholders. None matched a Titan account.

Faav returned to the lead after 1 a.m. on September 5 and reconsidered what the backend might be doing. If Titan treated upn as a local application username rather than an Entra identity, an email address was the wrong input. He changed the value to admin. Titan mapped it to local user ID 1, which had the Admin role, and executed SELECT 1.

That sequence is the most useful part of the incident for teams adding agents to security work. The agent was good at patient enumeration and at following the trail left by changing error messages. It did ten days of work in the background while the researcher handled other leads. Yet the label upn anchored both models to the conventional meaning of the field. A person broke the stalemate by asking how this particular backend might misuse it. The disclosure supports a narrow conclusion: automation extended the search, while human interpretation supplied the decisive test. It does not show that an AI system independently found and proved the vulnerability.

What the 17.3 trillion figure covers

After the administrator query worked, Faav first found Titan's platform metadata. He reports that it included roughly 25,000 account and email records, 17,990 employee email records, 15,001 employee organization records and 355 database configurations. The directory covered a subset of Microsoft employees and included details such as job titles, departments and management relationships. He did not test whether those details could be used for social engineering.

A Bing analytics source was also reachable. Faav ran two one-row queries against its latest available partition and says the samples contained search, identifier and broad location fields. He did not identify people, correlate identifiers across services or construct profiles. Those limits matter because reachable data is not the same as data known to have been stolen. The disclosure documents a path and its potential scope, not evidence of exploitation by another party.

To measure that scope without copying the underlying records, Faav tested the 56 recovered routing values with SELECT 1. Thirty remained active. They resolved through 24 configurations to 17 ClickHouse analytics databases with 9,863 unique table names. He counted a single replica per shard and checked the result through both system.tables.total_rows and active system.parts metadata. Both methods produced 17,333,335,124,315 rows.

Row count is not person count, query count or the volume of unique source data. Analytics systems routinely keep transformed tables, old partitions and repeated material. That is why "17.3 trillion records exposed" would overstate the evidence. The defensible claim is still serious: the bypass gave an unauthenticated researcher administrator-level SQL access to an environment whose metadata described 17.3 trillion stored rows across 17 databases.

Claim checks cannot replace trust

Microsoft's own access-token guidance tells resource servers to validate a token before treating it as authorization. It says an application should first validate the signature and issuer, then apply checks such as matching the aud claim to the intended API. Titan appears to have reversed the trust order. It inspected tenant, audience, app ID and user values before proving that Microsoft had issued the token.

The distinction is easy to lose because JWTs are readable by design. Base64url encoding lets a server decode the header and payload without possessing a secret or public key. Decoding answers, "What does this token claim?" Signature verification answers, "Did the trusted issuer make this claim, and has it remained unchanged?" Authorization logic built on an unverified payload gives an attacker control of the facts that the policy evaluates.

The IETF's JWT security guidance, RFC 8725 addresses the same failure class. Implementations must verify that the algorithm is allowed for the application, and libraries should reject none unless the caller explicitly requests unsecured JWTs. A maintained identity library can handle signature verification, issuer metadata, allowed algorithms and signing-key rotation. Application code still has to call it correctly and reject the request when verification fails.

Titan shows why a long chain of plausible checks can offer false comfort. Its tenant, audience and application filters generated distinct errors and slowed the investigation. Once the signature was optional, however, every accepted claim came from the person making the request. Adding another claim check would only have added another value to forge.

Four days from report to lockdown

Faav reported the issue to the Microsoft Security Response Center on September 5 as case 144051. MSRC asked him to stop testing and requested his IP address so it could distinguish his activity during its investigation. The API endpoint was locked down on September 9, and Microsoft awarded a $5,000 bounty on September 17. The two sides met on September 22 to coordinate publication.

There is one more constraint on the public record: Faav says Microsoft had editorial control over the disclosure and removed some sections and figures before publication. Microsoft's quoted response confirms that it investigated the report and hardened its services, but it does not independently confirm the 17.3 trillion estimate or describe the code change. No CVE, technical advisory or evidence of prior abuse appears in the published material.

The unanswered part is the scope of Microsoft's review. Similar internal analytics services may share Titan's token-validation path, and service logs may show whether unsigned tokens were accepted before Faav's report. Microsoft has not published its own technical account of the fix. For developers, the immediate check is concrete: find every place an API accepts a JWT, then verify that signature failure ends the request before a single claim reaches authorization code.

We reviewed this

  1. analytics — our honest review
  2. query — our honest review
  3. ClickHouse — our honest review

Sources

  1. How I Could've Accessed 17 Trillion Microsoft Records
  2. Access tokens in the Microsoft identity platform
  3. RFC 8725: JSON Web Token Best Current Practices