back to blog
HighCryptography

How an X.com Feature Flag Leaked Enterprise Customer Identities

valkant/May 2026

Feature flag platforms are now part of the default stack at almost every modern company. GrowthBook is one of the popular ones. It lets you encrypt the flag configuration on your server and decrypt it on the client so the actual rules are not visible in plaintext to anyone who opens DevTools. The encryption is good. The problem is what happens when the decryption key ends up somewhere it should not be.

On one of xAI's properties tied to X, we found that the GrowthBook decryption key was being serialised into the React Server Components payload. RSC payloads are streamed from the server to the browser as part of how the new Next.js rendering model works. They are not meant to be read by humans. They are also not meant to contain secrets. Anyone who opened the network tab could grab the payload, extract the key, and then decrypt every feature flag rule on the property.

On most apps that would be embarrassing but limited. Feature flag rules usually look like booleans and percentages. On a large enterprise platform, they look very different. The decrypted ruleset on this property contained user segmentation logic targeting specific enterprise customers. Customer identifiers were embedded directly in the rules. With the key in hand, we could read the names of paying enterprise tenants, which features they had access to, and which experiments they were being silently enrolled in.

We reported this through xAI's security program. It was triaged as High with a CVSS of 7.5, reflecting both the data sensitivity and the trivial exploitability. The fix is what you would expect. Stop serialising the decryption key into anything that crosses the trust boundary. Treat the RSC payload as a public document. If a secret cannot survive being printed on a billboard, it should not be in the payload.

This bug class is going to get more common, not less. Server Components are the default in new Next.js applications. Teams are rapidly migrating to them without fully internalising what gets serialised across the boundary. The line between server-only and client-visible is genuinely subtle in the new model. We are already finding similar issues in other RSC-based applications. Feature flag keys, analytics tokens, internal service URLs. Anything you assumed lived in the server module graph because the import was on the server side.

The takeaway for builders is not to fear RSC. It is to audit your payloads. View the raw RSC stream in a browser the same way an attacker will. Search it for the strings you would be unhappy about seeing. Then fix what comes up. The audit takes thirty minutes. The bug takes thirty seconds to find from the other side.