Unauthorized access to a support tool impacts Cloudflare customers

On August 23rd, Cloudflare was notified that the Salesloft Drift breach affected both us and our customers. A threat actor gained access to our Salesforce instance—used for customer support and internal case management—through compromised OAuth credentials from the Drift chat integration. While most of the exposed data consists of customer contact information and basic support case details, some support interactions contain configuration information and may include sensitive items such as access tokens.

Because Salesforce case data includes the full contents of support tickets, anything shared with Cloudflare through this channel—including logs, tokens, or passwords—should be considered compromised. We urge customers to rotate any credentials shared in support cases. Our review of the compromised data identified 104 Cloudflare API tokens; all have been rotated out of caution, and we found no suspicious activity associated with them. Affected customers have been notified directly. No Cloudflare services or infrastructure were compromised in this incident.

BLOG-2945  hero image

What happened

Cloudflare uses Salesforce for customer relationship management and as a support tool. The threat actor accessed only data within Salesforce "cases"—records created when sales and support teams collaborate internally or when customers contact support. Cloudflare’s Salesforce instance was integrated with the Salesloft Drift chatbot, which visitors used to contact us.

Salesloft announced that a threat actor breached their systems and obtained OAuth credentials for the Drift chat agent’s Salesforce integration. This enabled exfiltration from multiple Salesforce instances. Cloudflare’s threat intelligence team, Cloudforce One, classified the actor as GRUB1. Google’s Threat Intelligence Group published findings matching the activity we observed.

Our investigation determined that between August 12–17, 2025, following reconnaissance on August 9, the threat actor compromised and exfiltrated data from our Salesforce tenant. The exposure was limited to case objects: contact information, subject lines, and case correspondence bodies. Attachments were not exposed. Cloudflare does not require customers to share secrets, credentials, or API keys in support cases, but customers may paste such material during troubleshooting—anything shared this way should now be treated as compromised.

We believe this was part of a broader campaign to harvest credentials and customer information for future targeted attacks. Given the hundreds of organizations affected through the Drift compromise, the threat actor will likely leverage the stolen data against customers of those organizations.

Response and containment

Upon notification on August 23, Cloudflare launched a company-wide security incident response with cross-functional teams from Security, IT, Product, Legal, Communications, and business leadership. Our response focused on four workstreams:

  1. Immediate threat containment: Disabled the compromised Drift integration, conducted forensic analysis, and eliminated the active threat.
  2. Securing the third-party ecosystem: Disconnected all Salesforce integrations, issued new secrets, and implemented weekly rotation.
  3. Safeguarding broader systems: Expanded credential rotation across all third-party internet services and accounts as a precaution.
  4. Customer impact analysis: Examined Salesforce case data to identify affected customers and ensure timely communication.

Investigation timeline

Cloudflare became aware of suspicious activity within the Salesforce tenant when the company learned that hundreds of organizations, including our own, were targets of a supply chain attack. The attacker exfiltrated text fields from support cases. The security team immediately started an investigation, cut off the attacker’s access, and secured the environment.

An important detail: the attacker only accessed data within Salesforce cases. These are created when support and sales team members need to coordinate internally or when customers interact with support through the Drift chatbot on our website.

This incident underscores our responsibility in selecting the tools we use. We sincerely apologize to customers affected by this breach. Below we provide a detailed timeline and the steps we took during our investigation.

Reconstructing the attack

Cloudflare's forensic investigation pieced together the threat actor's activities, which took place between August 9 and August 17, 2025. The attacker, referred to as GRUB1, moved through distinct phases: initial reconnaissance, credential compromise, environment mapping, and finally a bulk data exfiltration.

Reconnaissance and initial access

The first sign of hostile activity came on August 9 at 11:51, when GRUB1 attempted to validate a Cloudflare-issued API token against the Salesforce API. Using Trufflehog as their User-Agent, the actor sent a verification request to client/v4/user/tokens/verify, which failed with a 404 Not Found, confirming the token was invalid. The origin of that token remains unclear.

Three days later, at 22:14 on August 12, GRUB1 successfully logged into Cloudflare's Salesforce tenant using a stolen credential belonging to the Salesloft integration. From the IP address 44[.]215[.]108[.]109, the attacker issued a GET request to the /services/data/v58.0/sobjects/ endpoint, enumerating all objects in the environment to gain a high-level view of the data stored there.

Environment mapping

Over the following days, the attacker methodically built a detailed picture of Cloudflare's Salesforce setup. On August 13, starting at 19:33, GRUB1 returned and retrieved the case objects' schema via the /sobjects/Case/describe/ endpoint, followed by a broad query enumerating fields from the case object. The subsequent day, August 14, was dedicated to comprehensive reconnaissance, including:

  • 00:17 — Counting accounts, contacts, and users to measure tenant scale
  • 04:34 — Querying CaseTeamMemberHistory to analyze case workflows
  • 11:09 — Fingerprinting the Organization object to confirm a production environment

Further queries mapped how the support team handles cases—assignment, escalation, and process flow—and the attacker queried the /limits/ endpoint to learn API operational thresholds, presumably to avoid tripping detection mechanisms during the eventual exfiltration.

After nearly 48 hours of silence, GRUB1 logged back in on August 16 at 19:26. At 19:28, they executed a single query—SELECT COUNT() FROM Case—a final dry run to confirm the dataset size before launching the main operation.

Exfiltration and cleanup

On August 17, the attacker switched infrastructure, logging in at 11:11:23 from IP address 208[.]68[.]36[.]90. After one final size check, they launched a Salesforce Bulk API 2.0 job at 11:11:56. In just over three minutes, GRUB1 exfiltrated the text content of support cases—not attachments or files. At 11:15:42, they attempted to delete the API job to cover their tracks, but Cloudflare's team reconstructed the attack from residual logs. No further activity from this actor was observed after August 17.

Discovery and containment

Cloudflare was not initially aware of the breach. Salesloft revoked Drift-to-Salesforce connections across its customer base on August 20 and published a notice, but Cloudflare had no indication this action related to its environment. Notification finally came on August 23 from both Salesforce and Salesloft regarding unusual Drift-related activity.

By August 25, Cloudflare escalated beyond vendor-recommended steps. The response effort focused first on eliminating the access vector: disabling the Drift user account, revoking its client ID and secrets, and purging all Salesloft software and browser extensions from Cloudflare systems. The security review expanded to all third-party services connected to Salesforce, with credentials rotated as a precaution against lateral movement.

Assessing data exposure

Because Salesforce is Cloudflare's primary tool for customer support data, the critical question was whether customers had submitted secrets or credentials in support requests. The investigation confirmed exposure was strictly limited to freeform text in Salesforce case objects, consisting of:

  • The subject line of the Salesforce case
  • The body of the case (freeform text, which may include correspondence, keys, secrets, or other materials if provided by the customer)
  • Customer contact information (company name, requestor email and phone, company domain, and country)

Cloudflare's teams developed custom scanning tools using regex, entropy, and pattern-matching to detect likely secrets at scale. This analysis led to the rotation of 104 Cloudflare platform-issued API tokens. No suspicious activity has been identified related to those tokens.

Following the analysis, all impacted customers were formally notified on September 2 via email and Dashboard banners, with recommended next steps. Additional response measures included terminating and securely re-establishing third-party integrations, with each re-onboarded service provisioned with new secrets and subject to stricter security controls.

Indicators of compromise

Cloudflare has published the indicators of compromise (IOCs) observed from GRUB1 so other organizations—particularly those potentially impacted by the Salesloft breach—can search their logs to confirm whether the same threat actor accessed their systems or third parties.

Indicator

Type

Description

208[.]68[.]36[.]90

IPV4

DigitalOcean based infrastructure 

44[.]215[.]108[.]109

IPV4

AWS based infrastructure 

TruffleHog

User Agent

Open source Secret Scanning tool

Salesforce-Multi-Org-Fetcher/1.0

User Agent

User-Agent string linked to malicious tooling

Salesforce-CLI/1.0

User Agent

Salesforce Command Line Interface (CLI),

python-requests/2.32.4

User Agent

User agent may indicate custom scripting 

Python/3.11 aiohttp/3.12.15

User Agent

User agent which may allow many API calls in parallel

Owning the Outcome

Cloudflare is responsible for the third-party tools it chooses to integrate into its environment. When a sophisticated actor compromises one of those tools, the consequences are ours to address. Upon receiving notice of the incident, our investigation confirmed that the exposure was strictly limited to data stored in Salesforce case objects. No other Cloudflare systems or infrastructure were affected.

Still, the compromise of any data is unacceptable. Our customers trust us with their data and infrastructure, and we extend that trust to external tools that must be carefully scoped and monitored. In this instance, we let our customers down, and we sincerely apologize.

The incident is a reminder that as third-party tools increasingly connect to internal corporate data, each new integration point must be scrutinized. Through a single integration, this attack affected hundreds of organizations, illustrating the interconnected risk in today's technology landscape. We are committed to building new capabilities to help defend against such attacks—look for announcements during Cloudflare's Birthday Week later this month.

We are also committed to sharing threat intelligence with the security community. In the coming weeks, our Cloudforce One team will publish a detailed analysis of GRUB1's tradecraft to support defenders facing similar campaigns.

Incident Timeline

The table below details GRUB1's specific actions chronologically during the incident.

Date/Time (UTC)

Event Description

2025-08-09 11:51:13

GRUB1 observed leveraging Trufflehog and attempting to verify a token against a Cloudflare Customer Tenant: client/v4/user/tokens/verify, and received a 404 error from 44[.]215[.]108[.]109

2025-08-12 22:14:08

GRUB1 logged into Cloudflare’s Salesforce tenant from 44[.]215[.]108[.]109

2025-08-12 22:14:09

GRUB1 sent a GET request for a list of objects in Cloudflare’s Salesforce tenant: /services/data/v58.0/sobjects/

2025-08-13 19:33:02

GRUB1 logged into Cloudflare’s Salesforce tenant from 44[.]215[.]108[.]109

2025-08-13 19:33:03

GRUB1 sent a GET request for a list of objects in Cloudflare's Salesforce tenant: /services/data/v58.0/sobjects/

2025-08-13 19:33:07 and 19:33:09

GRUB1 sent a GET request for metadata information for case in Cloudflare’s Salesforce tenant: /services/data/v58.0/sobjects/Case/describe/

2025-08-13 19:33:11

GRUB1 first observed executing Salesforce query: A broad query against the case object by 44[.]215[.]108[.]109. This produced one of the earliest and larger data responses, consistent with reconnaissance via bulk record retrieval

2025-08-14 0:17:40

GRUB1 lists available objects and counts “Account”, “Contact” and “User” objects.

2025-08-14 00:17:47

GRUB1 queried Account table in Cloudflare’s Salesforce tenant: “SELECT COUNT() FROM Account” query on Cloudflare’s Salesforce tenant

2025-08-14 00:17:51

GRUB1 queried Contact table in Cloudflare’s Salesforce tenant: “SELECT COUNT() FROM Contact” query on Cloudflare’s Salesforce tenant

2025-08-14 00:18:00

GRUB1 queried User table in Cloudflare’s Salesforce tenant: “SELECT COUNT() FROM User” query on Cloudflare’s Salesforce tenant

2025-08-14 04:34:39

GRUB1 queried "CaseTeamMemberHistory” in Cloudflare’s Salesforce tenant: “SELECT Id, IsDeleted, Name, CreatedDate, CreatedById, LastModifiedDate, LastModifiedById, SystemModstamp, LastViewedDate, LastReferencedDate, Case__c FROM CaseTeamMemberHistory__c LIMIT 5000”

2025-08-14 11:09:14

GRUB1 queried Organization table in Cloudflare’s Salesforce tenant: “SELECT Id, Name, OrganizationType, InstanceName, IsSandbox FROM Organization LIMIT 1”

2025-08-14 11:09:21

GRUB1 queried User table in Cloudflare’s Salesforce tenant: “SELECT Id, Username, Email, FirstName, LastName, Name, Title, CompanyName, Department, Division, Phone, MobilePhone, IsActive, LastLoginDate, CreatedDate, LastModifiedDate, TimeZoneSidKey, LocaleSidKey, LanguageLocaleKey, EmailEncodingKey FROM User WHERE IsActive = :x ORDER BY LastLoginDate DESC NULLS LAST LIMIT 20”

2025-08-14 11:09:22

GRUB1 sent a GET request on LimitSnapshot in Cloudflare’s Salesforce tenant: /services/data/v58.0/limits/

2025-08-16 19:26:37

GRUB1 logged into Cloudflare’s Salesforce tenant from  44[.]215[.]108[.]109

2025-08-16 19:28:08

GRUB1 queried Cases table in Cloudflare’s Salesforce tenant: SELECT COUNT() FROM Case

2025-08-17 11:11:23

GRUB1 logged into Cloudflare’s Salesforce tenant from 208[.]68[.]36[.]90

2025-08-17 11:11:55

GRUB1 queried Case table in Cloudflare’s Salesforce tenant: SELECT COUNT() FROM Case

2025-08-17 11:11:56 to 11:15:18

GRUB1 leveraged Salesforce BulkAPI 2.0 from 208[.]68[.]36[.]90 to execute a job to exfiltrate the Cases object 

2025-08-17 11:15:42

GRUB1 leveraged Salesforce Bulk API 2.0 from 208[.]68[.]36[.]90 to delete the recently executed job used to exfiltrate the Cases object