← All field notes
saasprivate app tokenfor administrators

HubSpot private-app token leaks: rotate the token, not the admin

A leaked HubSpot private-app token can paginate the whole CRM out the door. The principal is the token, so you rotate it in the private app, not reset the admin who built it.

A HubSpot private app authenticates with its own access token, a non-human identity that holds standing CRM access. If that token leaks into a frontend bundle or a shared script, it keeps working with no user session behind it.

How the attack works

The leaked token is used from a host outside the integration’s normal infrastructure. Instead of the scheduled recent-changes delta the app normally syncs, it paginates the contacts and companies endpoints from the very start, then pulls hundreds of thousands of contact, company, and deal records with properties: emails, phone numbers, and pipeline values. The full dataset is staged off-platform for resale or phishing. In ATT&CK terms this is T1552, Unsecured Credentials, with T1213, Data from Information Repositories, and T1567 for the exfiltration over a web service.

Why it works

The private app has CRM read scopes by design, so the reads are authorized. The malicious tell is the shift from a small scheduled delta to a full-database pagination from a new source. A broadly scoped, non-expiring token that has leaked turns a routine integration into a bulk export channel.

How to fix it

Rotate or delete the private app’s access token in HubSpot, which immediately invalidates it and breaks the integration’s auth. Do not reset the creating admin’s password, because the token is decoupled from any login, and an IP block is trivially evaded. Scope the export from the API call log filtered to the token and window, since granted scope shows capability, not activity. For the class, inventory all private apps, down-scope to least privilege, add secret scanning across code and frontend bundles, and prefer delta reads. CRM contacts are personal data, so breach-notification duties follow the data subjects’ jurisdictions and the customer DPA.

Practice it

We built this as a GraphLattice Range scenario so administrators can rehearse rotating the right token, scoping the export, and down-scoping the private-app fleet.