A decommissioned OVH server left running an unpatched analytics tool gave attackers a six-hour window inside Double Counter’s Google Cloud environment. It ended with a stolen Discord bot token, ~12 GB of copied database records, spam broadcasts to roughly 50 large Discord communities, and $7,316 in fraudulent card charges. This is the full technical account of the October 4, 2026 incident.
On October 4, 2026, an attacker moved from a retired legacy server into the production Google Cloud Platform (GCP) infrastructure of Double Counter in under twelve hours. Double Counter is one of Discord’s most widely deployed verification and alt-detection bots, serving more than 600,000 communities and roughly 3.7 million monthly users since its 2020 launch. The attacker’s last recorded action in the cloud came at 17:54:57 UTC, and the service was restored with fully rotated credentials at 19:19 UTC the same day.
The incident is a near-textbook case of three persistent failure classes in cloud security: incomplete decommissioning of legacy infrastructure, over-privileged non-human identities (service accounts with static, long-lived keys), and secrets stored where running workloads can read them. Defenders also rarely see this level of candor in a published report. The attacker adapted to each containment step and read a freshly rotated bot token within two minutes of its deployment, because the token was still reachable from inside compromised containers.
Double Counter’s founder, Nathan, disclosed the breach publicly on October 5, 2026, telling the community that “all known access has been revoked, and Double Counter is operational.” He also confirmed that all financial data for paying customers remained safe. This analysis draws on three primary sources: the detailed incident report published the same day, the notification to France’s data protection authority (CNIL), and the subsequent Have I Been Pwned listing.
Key facts at a glance
- Initial access: a legacy, out-of-service OVH server still running a publicly reachable self-hosted Metabase instance. A vulnerability in the analytics tool let the attacker forge an administrator session and reach the host.
- Cloud pivot: two legitimate credentials stored on that server, a GCP service-account key with administrator rights and a saved administrator command-line session, were used to enter the cloud project at 12:03 UTC. No new accounts were created, so early activity blended into normal audit noise.
- Dwell time in the cloud: 5 hours 51 minutes (12:03 to 17:54 UTC), across two credential sets.
- Data copied: about 12 GB exfiltrated between 15:09 and 15:34 UTC. A separate 5.0 GB full database export created at 12:35 UTC was never downloaded.
- Discord abuse: the bot token was read from a running container at 12:26 UTC. From 13:30 UTC the attacker used it to post invitations to their own server in about 50 large communities, appearing as legitimate Double Counter messages.
- Financial fraud: a stolen Stripe key belonging to a separate product (Atis) was used for $7,316 in fraudulent charges, including two customer charges ($3 and $15) that have been refunded.
- Exposed personal data (treated as exposed): ~28 million Discord user IDs and usernames, ~27 million IP addresses with coarse geolocation, ~25 million user-agent hashes, and ~1.0 million de-duplicated email addresses.
- Regulatory status: CNIL notified October 5, 2026 under reference FR2610050000001. Criminal complaints are being prepared in France and the United States.
initial access through a server nobody owned
The attack chain was set up long before October 2026. The entry point was an old production server from Double Counter’s previous OVH hosting setup. It was no longer in use and no longer linked to the operational service, so presumably it was no longer anyone’s job. Retired infrastructure that stays powered on and reachable is a common attack surface, and this incident joins a long line of breaches where the compromised asset was the leftover of an earlier production environment.
Starting at 04:37 UTC on October 3, the attacker probed the legacy server and an internal API from rotating VPN addresses. They then worked through a list of plausible usernames: root, nathan, debian, and service-style names such as analytics-sync and metabase. At 00:47 UTC on October 4 they logged in. The report says the login “took only a few tries once they reached the right account,” so the weakness was the exposed server, not the strength of any credential.
The way in was Metabase, the open-source Java-based business intelligence and analytics platform, still running and publicly reachable on the retired host. A vulnerability in the tool let the attacker forge an administrator session and, from that administrative context, reach the underlying host and the credentials stored on it. Double Counter says no password leaked from source code, because their code contains none. The vector was a live, exploitable application on a forgotten machine.
Self-hosted Metabase has a documented exploitation history, most prominently CVE-2023-38646, a pre-authentication remote code execution flaw (CVSS 9.8) disclosed in July 2023 and mass-exploited in the wild to deploy botnets and cryptominers against internet-exposed instances. Double Counter’s report does not name a specific CVE. Still, forging an administrative session on an exposed instance to get host-level access matches what security teams have been mitigating for years on Metabase and similar self-hosted BI tools such as Grafana, Superset, and phpMyAdmin: internet-facing administrative interfaces with stale patch levels.
What the server held made the foothold catastrophic. Two credentials for Double Counter’s cloud environment were stored there. One was the key of a service account (a non-human identity that services use to authenticate to GCP) with administrator rights. The other was an administrator’s saved command-line session. The attacker created no accounts and exploited no cloud vulnerability. They presented two valid, highly privileged credentials, which is why the earliest cloud-side activity blended in. To the cloud control plane, everything looked like Double Counter acting as itself.
cloud entry with valid accounts (12:03 to 12:35)
The service-account key was first used against Double Counter’s cloud project at 12:03 UTC. Five minutes later, at 12:08, the attacker added their own SSH key to the project, a classic cloud account-manipulation technique that gives durable interactive access without touching passwords. Between 12:19 and 12:35 they exported one of the company’s databases into a storage bucket they created inside the victim project. The 5.0 GB export was never downloaded. The report does not say whether the attacker abandoned it, was interrupted, or simply moved on to the later table-level copy. Either way, Double Counter’s exposure accounting does not rely on it.
📬 Stay Ahead of Cyber Threats
Get the latest cybersecurity news, critical vulnerabilities, threat intelligence, tutorials, and exclusive giveaways delivered straight to your inbox. No spam. Unsubscribe anytime.
Subscribe to the Newsletter →Two points stand out for cloud defenders. The ability to add project-wide SSH keys implies the service account held compute-level administrative permissions far beyond what any single service needs, which makes this a privilege-scoping failure as much as a key-management one. And exporting into a bucket inside the victim’s own project was operationally clever: it uses the victim’s storage quota and egress paths, avoids immediate cross-account transfer alerts, and leaves artifacts that double as evidence. Google’s guidance has long recommended blocking long-lived service-account key creation through organization policy constraints and preferring workload identity federation with short-lived credentials. A static key is a password that never expires and never prompts for MFA.
bot token theft and the abuse of a trusted identity (12:26 to 13:39)
At 12:26 UTC the attacker opened a shell inside a running bot container and read the Discord bot token from its environment. This turned a cloud intrusion into a community-wide incident. A bot token is a bearer secret with no second factor, interactive login, or device trust, so whoever holds it is the bot. Rotation is the only way to revoke it, and rotation only works if the new token never passes through a compromised environment again.
Between 13:24 and 13:34 UTC the attacker used the token on Double Counter’s own support server. At 13:24 they granted their account (Discord ID 931487207443804161) Administrator rights, and at 13:26 they stacked about 15 roles. Staff banned them at 13:32, they used the bot to unban themselves at 13:33, and they were banned again at 13:34. From 13:30 UTC onward, the compromised bot posted invitations to the attacker’s Discord server in roughly 50 large communities that use Double Counter for verification. According to the report, the largest targeted server was “Steal a brainrot,” a community associated with a popular Roblox game mode.
Because the messages went straight through Discord’s API under the bot’s legitimate identity, they bypassed Double Counter’s own logging. The company later reconstructed the affected server list from community reports and the bot’s message history. Bot operators should plan for that evidentiary gap before an incident, not during one.
Double Counter invalidated the token at 13:39 UTC, which took the bot offline and ended the broadcast window. By about 14:45 a new token was installed, and verifications resumed at 14:49. That fix lasted about two minutes.
rotation inside a compromised runtime (14:46 to 15:34)
Between 14:46 and 14:51 UTC the attacker opened new shells into containers and read the newly issued token within two minutes of its deployment. This detail matters most for other teams. Rotating the token is the right response to token theft, but only after the theft channel is closed. The token was still injectable into, or readable from, running containers the attacker could shell into, so rotation only refreshed the attacker’s session. Rotating credentials inside a compromised trust boundary achieves nothing. Restore the boundary first (workload restarts on clean images, environment scrubbing, node replacement), then introduce new secrets.
The attacker then moved to disruption. Between 15:04 and 15:09 they deleted backups they had created and changed the database administrator password. That locked Double Counter’s own services out of their database and halted verifications, which slowed the response while the copy ran. From 15:09 to 15:34, working from a cloud-hosted machine, they copied database tables until Double Counter located and terminated the session at about 15:34.
About 12 GB in roughly 25 minutes works out to a sustained transfer on the order of 8 MB/s, consistent with bulk table extraction over internal cloud networking and not a slow, stealthy drip. That bluntness made reconstruction possible. Double Counter’s copy tool traverses tables in a fixed order, so the team could compare the volume that left against known table sizes and work out, table by table, what was fully copied, partially copied, or untouched. For the interrupted table, the verified users’ IP records (~21.7 million rows), they estimate about 20% had left before termination. Nobody can tell which 20%, so the entire table is treated as exposed. That is the right call under GDPR risk-assessment logic, and it matches how mature vendors handle partial exfiltration: when the affected rows can’t be identified, assume all of them.
Detection arrived at 15:17 UTC through cloud audit logs, roughly three hours and fourteen minutes after the first malicious use of the service-account key. Discord-side abuse had already triggered a response at 13:39. The gap between 12:03 and 15:17 is the cost of an intrusion that starts with valid credentials: nothing in the early audit trail looks anomalous until someone correlates it against known-good behavior.
fallback credentials, payment fraud, and final eviction (15:54 to 19:19)
Double Counter disabled the service-account key at 15:20 and deleted the attacker’s SSH key at 15:21. The attacker then fell back to the second credential harvested from the legacy server, the administrator’s saved session. Between 15:54 and 16:46 they re-established container shells and database connections, though the report records no measurable data transfer in this phase. At about 16:08 Double Counter made the blunt but correct decision to take the entire service offline to sever the fallback path. The bot token was reset again and moved into a dedicated secret store at about 16:19. Between 16:25 and 16:52 the cache database was migrated off its third-party, internet-facing host onto a private network with no public address.
Later, at 17:11 to 17:12 UTC, the attacker reached into Double Counter’s sibling product line. Among the secrets readable in the cloud environment was the Stripe key for Atis, a separate Tellter product. They used it to run escalating test charges ($1, $10, $100, $1,000) against one of the company’s own cards, totaling $7,316, plus two small charges ($3 and $15) against two Atis customers, both refunded in full. The published ladder sums to far less than the stated total, which suggests the escalation cycled several times within that one-minute window. That fits automated card-testing tooling probing charge limits before the keys were revoked at 17:14.
No stored card numbers were exposed. Card data sits with the payment provider under its own PCI DSS scope, and the attacker acted through the account, not against cardholder data. Key compromise and data compromise are different things: this was a fraud incident, not a payment-card breach, and Double Counter’s report draws that line precisely.
Final eviction came at about 17:55 UTC, when all sessions of the administrator account were revoked. The attacker’s last recorded action was at 17:54:57. The legacy OVH server was shut down around 18:00, and an audit of 14 cloud projects between 18:00 and 18:40 found no persistence: no lingering keys, accounts, permissions, machines, scheduled jobs, or container images. The attacker made one last move at about 18:35, posting invitations in the support server through two exposed webhooks. All ten potentially exposed Discord webhooks were deleted by about 18:40. Between 19:11 and 19:16 the team enabled logging of every secret read, armed alerting on sensitive cloud changes, replaced all session-signing keys (forcing a global sign-out), and reset the bot token a final time. Double Counter returned to service at 19:19 UTC with new credentials, and new webhooks, whose addresses are held only in the secret store, entered service at 19:40.
The complete timeline
| Time (UTC) | Actor | Event |
|---|---|---|
| Oct 3, 04:37 | Attacker | First probing of legacy OVH server and internal API from rotating VPN addresses |
| Oct 4, 00:47 | Attacker | Login to legacy server via Metabase vulnerability after username enumeration |
| 12:03 | Attacker | First use of service-account key in cloud |
| 12:08 | Attacker | SSH key added to cloud project |
| 12:19 to 12:35 | Attacker | Database export to attacker-created bucket (5.0 GB; never downloaded) |
| 12:26 | Attacker | Shell in bot container; bot token obtained |
| 13:24 to 13:34 | Attacker | Support server: Administrator granted, ~15 roles, staff ban, bot-driven unban, re-ban |
| 13:30 | Attacker | Bot begins posting attacker server links in ~50 large servers |
| 13:39 | Response | Bot token invalidated; bot offline |
| ~14:45 | Response | New bot token installed; verifications resume 14:49 |
| 14:46 to 14:51 | Attacker | New container shells; new token exposed within ~2 minutes |
| 14:57 | Response | Real-time monitoring of bot-granted permissions goes live |
| 15:04 to 15:09 | Attacker | Backups deleted; database admin password changed; verifications stop |
| 15:09 to 15:34 | Attacker | ~12 GB of database tables copied |
| 15:17 | Response | Intrusion identified in cloud audit logs |
| 15:20 to 15:24 | Response | Service key disabled; deletion protection on; SSH key removed; database closed to internet |
| 15:28 | Response | New database password; verifications resume |
| ~15:34 | Response | Attacker’s copy session located and terminated |
| 15:36 | Response | Stolen key deleted; service account disabled and stripped |
| 15:54 to 16:46 | Attacker | Fallback administrator session: container shells, database connections |
| ~16:08 | Response | Double Counter deliberately taken offline |
| ~16:19 | Response | Bot token reset, moved to secret store |
| 16:25 to 16:52 | Response | Cache database migrated to private network |
| 17:11 to 17:12 | Attacker | Fraudulent Stripe charges on separate Atis account ($7,316 total) |
| 17:14 | Response | All payment-provider keys revoked; customer charges refunded |
| 17:33 to 17:54 | Attacker | SSH key re-added; five database connections; last action 17:54:57 |
| ~17:55 | Response | All administrator sessions revoked; attacker cloud access ends |
| ~18:00 | Response | Legacy OVH server shut down |
| 18:00 to 18:40 | Response | Backdoor audit of 14 projects (clean); database password replaced again (18:15) |
| ~18:35 / ~18:40 | Attacker / Response | Invites posted via two webhooks; all ten exposed webhooks deleted |
| 19:11 to 19:16 | Response | Secret-read logging enabled; alerting armed; session-signing keys replaced; final token reset |
| 19:19 | Response | Service restored with new credentials |
What data was exposed, and how Double Counter knows
The exposure accounting published on October 5 is unusually granular. Because the copy tool reads tables in a fixed order, comparing byte volume against table sizes gives a verdict for each table:
Data Records Status Discord user IDs and usernames of affected accounts ~28 M Partly copied (treated as exposed) IP addresses and coarse geolocation (country, region, city, postal code, ISP) ~27 M Partly copied (treated as exposed) User-agent hash (one-way hash of browser user agent, city, country; used for alt detection) ~25 M Copied Email addresses, de-duplicated (Doogle accounts ~840k; dashboard, server-manager, customer and advertiser contacts ~240k) ~1.0 M Copied VPN detection logs (IP addresses and user agents) ~15 M Not copied Behavioural fingerprints (product events, device/browser characteristics, acquisition tracking) ~25 M Not copied, stored elsewhere Cold storage database (~58 M users, only ~800k emails; not used by main verification) ~58 M Not affected Full export of affected database created at 12:35 5.0 GB Not downloaded
The IP-address records live in two tables. The alt-detection table (~5.4 M rows) was copied in full, while the verified-users table (~21.7 M rows) was interrupted at an estimated 20%. Since the specific rows can’t be identified, the whole set is treated as exposed. User-agent hashes are one-way, but they remain linkable quasi-identifiers. A hash of user agent plus city and country stays stable across sessions for a given user, which made it useful for alt detection and also gives it residual privacy value. Coarse geolocation including postal codes counts as personal data under GDPR, and for some paying subscribers the combination of email, name, country, and postcode comes close to a directly identifying profile.
The affected database did not contain Discord passwords (Double Counter never receives them) or stored payment card details, which are held by the payment provider. The ~58 M-user cold-storage database and the behavioural-fingerprint store, which sits on separate infrastructure, were also outside it. Double Counter also confirms that the payment account processing Double Counter and Doogle subscriptions shows no unauthorized charges. The fraud hit a separate product’s account.
Have I Been Pwned’s listing for the incident catalogs exposed classes including email addresses, Discord usernames, names, geographic information, and country plus postcode for some paying subscribers. It correlates approximately 275,000 unique email addresses. The gap between that figure and the vendor’s ~1.0 M de-duplicated estimate comes from different evidentiary standards. Double Counter applies a precautionary approach to everything the copy process touched or might have touched. Breach-indexing services typically enumerate confirmed, deduplicated records available for verification, often weighted toward subscriber and contact populations and not platform-internal account sets. Users should treat the vendor’s higher figure as the operative risk boundary.
Discord-side fallout: fifty communities, one trusted identity
Messages inviting members to the attacker’s server appeared in about 50 large Double Counter-using communities. They came from the bot’s legitimate identity, so at a glance they looked like genuine service messages. Substantially all have since been deleted by Double Counter or by individual moderation teams. On the support server, the attacker’s account accumulated Administrator rights and roughly fifteen roles before staff bans ended the session. Two webhooks were later used to post invitations after cloud access had already been cut. Webhook URLs are bearer-style credentials too, and they belong in secret storage with rotation policies like any other key.
Double Counter deliberately declined to link the attacker’s server in its report, and this article follows that practice. Server administrators should rely on the audit-log guidance below.
Response assessment: what Double Counter got right, and what let this happen
What went right
The response after detection was fast. Containment actions cluster within minutes of each other across the 15:17 to 15:36 window, and the decision to take the service offline at about 16:08 to sever a fallback credential path shows a willingness to trade availability for security under pressure. The post-incident hygiene is above average for a service of this size:
- a 14-project persistence audit that found nothing
- replacement of session-signing keys, forcing global re-authentication
- migration of the cache database off an internet-facing third-party host
- elimination of long-lived service-account keys
- a dedicated secret store for bot tokens and webhook addresses
- secret-read logging plus alerting on sensitive cloud changes, which instruments the exact blind spots the attacker used
Publishing a minute-level timeline, naming the fraud amounts, disclosing the two-minute token re-compromise, and treating partially copied tables as fully exposed show a level of candor most breached vendors never reach.
What let it happen
The causal chain is clear:
- a retired server left running a publicly reachable, vulnerable Metabase instance
- administrator-grade cloud credentials stored on that server
- a service account whose static key carried project-wide administrative rights, including SSH key management
- a database reachable from the internet
- backups an attacker session could delete
- bot tokens readable from container environments
None of these is exotic. Each is a default-ish convenience that survived organizational growth, and the two-minute re-compromise of the rotated token shows how they compound.
Why this breach matters beyond Discord
First, the non-human identity problem. Industry research on cloud intrusions repeatedly identifies static, over-privileged service-account keys as a top initial-access and persistence vector, because they lack MFA, never expire, and leave audit trails indistinguishable from legitimate automation. The attacker never needed a zero-day against GCP. One admin-grade key and one saved session were enough.
Second, the legacy decommissioning gap. Vulnerability management programs that scope only “production” systematically miss the retired hosts, staging boxes, and forgotten analytics instances that attackers probe first.
Third, the bearer-secret architecture of bot platforms. Discord bot tokens and webhook URLs grant identity and capability with no interactive friction, so token theft turns instantly into impersonation at the scale of the bot’s reputation. Here that meant the trust of 600,000 communities.
On the regulatory side, the incident tracks GDPR Article 33 cleanly. Containment came on October 4 and the CNIL notification on October 5 under reference FR2610050000001, comfortably inside the 72-hour window. The reference’s structure (FR + year + filing date + serial) is consistent with an October 5 filing. Direct user communication in the spirit of Article 34 is promised as logs are consolidated. Legal proceedings are being prepared in France and the United States, with counsel holding platform and Discord logs, direct-message screenshots, and technical indicators from Double Counter’s systems.
What you should do now
Server administrators
Delete any message sent by Double Counter on October 4 between 12:00 and 16:30 UTC that invites members to another server. Review your audit log for Double Counter actions in that window, such as permission changes, role edits, or channel posts you did not initiate. If your moderation team already purged invite spam that day, verify nothing was reposted via webhooks afterward.
Members
Nothing needs changing on your Discord account itself, since Double Counter never holds Discord passwords. Do not join servers advertised in unexpected Double Counter messages. If you verified between 13:39 and 14:49 UTC without receiving your role, verify again. Enable Discord two-factor authentication if you have not. It won’t stop token-side abuse, but it limits account takeover from downstream phishing.
Doogle, Atis, advertiser, and API customers
Doogle users, advertisers, and API customers should assume their email addresses are in phishing scope. Treat any message asking for passwords, tokens, or payment, especially one that references this breach, as hostile by default. Atis customers need take no action, because the two incident charges were refunded. Double Counter states that it never asks for passwords, tokens, or payment by email or private message. Breach-notification periods reliably produce secondary scam waves, and the email exposure here gives scammers a ready target list.
Bot operators and cloud teams
- Decommission legacy hosts formally. Shutdown, credential revocation, and secret scrubbing are one workflow, not three optional tasks.
- Prohibit long-lived service-account keys through organization policy and move to workload identity federation with short-lived tokens.
- Scope service accounts to the minimum API surface, and never give a workload identity compute SSH-key management.
- Keep databases off the public internet, behind private VPC paths.
- Treat any internet-facing administrative interface, Metabase included, as production-critical for patching.
- Store bot tokens and webhook URLs only in a secret manager with read logging.
- Design deployments so a rotated secret never passes through a runtime an attacker may already control.
- Make backups immutable or deletion-protected.
- Alert on the events that precede disaster: new SSH keys in a project, service-key usage from novel networks, and permission grants issued by your own bot.
Indicators and reference points
- Attacker Discord ID: 931487207443804161
- Malicious message window: Oct 4, 2026, 12:00 to 16:30 UTC (Double Counter-sent invites)
- Enumeration targets observed: root, nathan, debian, analytics-sync, metabase
- CNIL reference: FR2610050000001
- Primary sources: Double Counter incident report (published Oct 5, 2026), founder Nathan’s public statement (Oct 5, 2026), Have I Been Pwned breach listing
Frequently asked questions
Was my Discord password exposed in the Double Counter breach?
No. Double Counter’s verification flow never receives Discord passwords, and the affected database did not contain them. The exposed data is identifiers and technical attributes: Discord IDs and usernames, IP addresses with coarse geolocation, user-agent hashes, and around one million email addresses.
How do I check whether my email was affected?
Check your address against Have I Been Pwned, which has indexed the incident, and watch for phishing that references Double Counter, Doogle, or Atis. HIBP’s confirmed-record count (~275k unique emails) is narrower than the vendor’s precautionary estimate (~1.0M), so absence from HIBP does not prove your email was not exposed.
Is Double Counter safe to use again?
The service was restored at 19:19 UTC on October 4 with fully rotated credentials, a clean 14-project persistence audit, databases moved off the public internet, and secrets relocated to a dedicated secret store with read logging and change alerting. The residual risk now resembles that of any well-instrumented cloud service. The historical risk was organizational hygiene, which the report addresses directly.
Did attackers steal credit card numbers?
No. Card data is held by the payment provider, not Double Counter. The attacker abused a Stripe account key for the separate Atis product, producing $7,316 in fraudulent charges across three cards: one company card and two customer cards, both refunded. No stored card numbers were exposed.
Why could the attacker read the new bot token two minutes after rotation?
Rotation happened while the attacker still had shell access to the running containers where the token was materialized. New secrets injected into a compromised runtime are compromised on arrival, so the trust boundary has to be rebuilt before rotation has any effect.
What is the biggest lesson for other organizations?
Decommissioning has to revoke secrets and cut reachability in the same change window. A decommissioned OVH server running an unpatched, publicly reachable Metabase instance, and holding live administrator-grade cloud credentials, turned a forgotten asset into a six-hour production breach.
Bottom line
The attacker used ordinary techniques: scanning, exploiting an unpatched exposed app, presenting valid credentials, reading secrets from runtimes, and abusing a trusted identity. The weak points were administrative: a server nobody owned, a key with too many rights, a database facing the internet, and backups an intruder could delete. Double Counter’s disclosure is worth reading for its minute-level timeline, its admission that the first token rotation failed, its table-level exfiltration forensics, and its precautionary exposure counts. Teams that read the timeline will likely recognize their own legacy server, over-privileged service account, or secrets sitting one container shell away from an attacker.









