Incident report: July 1, 2026
On July 1st, 2026, an attacker obtained 1747 email addresses of users who linked their Lolli accounts with Mezo. The smart contracts, the chain, and the bridge were all unaffected, and all funds are safe. The team detected and responded to the attack in less than three hours. We will be in contact with all affected users.
Summary
The Mezo App available under mezo.org is deployed on Cloudflare and reads data both from the chain and from a database. One category of data stored in the database is cached on-chain transaction data like amounts, timestamps, and transaction hashes - all publicly visible on-chain. Caching in the database greatly improves the speed at which certain components of the app, like activity history, can be loaded. A second category of data is user email addresses, partner integration codes, and Terms of Service checks. Such data is only stored in the database and not persisted to the chain. The attacker copied five tables from this database: cached wallet addresses, cached deposit and withdrawal data, records of which users accepted our Terms of Service, and the Lolli integration table containing user email addresses and partner-integration codes. While email addresses in the Lolli integration table were exposed; the rest is either already public on-chain or contains no personal contact information.
The attack vector
The attacker used an old development build to extract a Cloudflare API token that gave them access to Mezo infrastructure on Cloudflare. A couple of months ago, a front-end build configuration in the code was mistakenly updated to inline the entire build environment directly into the JavaScript it produced. The mechanism is a two-line Vite misconfiguration in vite.config.ts whose effects only became security-relevant once the build moved into a container that carries credentials, when we migrated the Mezo app deployment from Netlify to Cloudflare. The build configuration was later updated to eliminate the problem, but the outdated preview deployment remained reachable. The attacker fetched it by scanning our domain, extracting the exposed token, and using it to deploy a malicious worker to exfiltrate the parts of the database.
Timeline (all times UTC)
- 05:32: attacker begins probing our systems from a Singapore VPN.
- 05:44: attacker uses the leaked token to deploy the first rogue Cloudflare worker.
- 06:25 - 07:14: rogue worker downloads the five tables and user data from Supabase.
- 07:50: team notices problems with mezo.org and begins investigating.
- 07:54: team rolls back the tampered worker to its last legitimate version.
- 08:07 - 08:14: team removes the compromised account's access and revokes the API token.
- 08:28: team begins rotating all Supabase keys and redeploying all workers from trusted CI.
Actions taken
Once we detected the intrusion, we moved first to cut off access to the attacker. We deleted the attacker's rogue workers and redeployed all of workers from trusted CI. We revoked the leaked Cloudflare API token, and went further, rotating every deployment secret and database access credential.We have surveyed the engineering team about their Cloudflare API keys and disconnected the Cloudflare GitHub application from all repositories, allowing only our custom CI actions to deploy workers and pages to Cloudflare. We fixed the piece of the build configuration that had exposed the token, confirmed that no other code in Mezo was affected by the same issue, and removed the deployments of all workers no longer in active use. We have also contacted the ISP and data center provider from which the attacker operated.We will be in contact with all affected users.
Lessons learned
The team detected this intrusion early, and responded quickly. That response time kept this incident from further escalating. Still, we can always do better, and will redouble our monitoring efforts to further reduce incident response time.While the token build exposure was an oversight from a one-time migration, it also stemmed from surprising and undocumented behavior from Cloudflare’s build process. Though we no longer use this particular feature, we’ve reached out to the Cloudflare team to give feedback on how this behavior contributed to the intrusion. We were also lucky. A more sophisticated, better prepared attacker could have done far more damage, escalating to a full site takeover. It’s not often in security that you catch a break.
Comments ()