Learn / Attack archive / Lesson 26
Stolen tokens and connected apps
Why a stolen session cookie or OAuth token skips the password and the second factor, how one chatbot integration opened 700 companies' Salesforce data, and how to make tokens worth less.
Last updated: 2026-09-23
What it is
After you sign in, the site gives your browser a session token, usually a cookie. After you connect one app to another ("Allow this app to access your Salesforce"), the app gets an OAuth token. Either one is proof that the login already happened.
So whoever holds the token does not need the password or the second factor. They are you, for as long as the token lives. Tokens get stolen in four common ways:
- Infostealer malware copies cookies straight out of the browser.
- Debug files that record traffic, such as browser HAR files sent to a support team, contain live cookies.
- Logs and code that print headers or keep tokens in plain text.
- A connected app is breached, and every token it holds for its customers goes with it.
Why it is a rule
- Linus Tech Tips, March 2023. An employee opened what looked like a sponsor's PDF. It was malware that copied browser session cookies. The attackers took over the channel's YouTube accounts, with millions of subscribers, without ever needing a password or second-factor code.
- Okta, October 2023. Customers uploaded HAR files to Okta's support system to debug problems. An attacker got into that system through a service account and pulled session tokens out of the files, then used them against customers including 1Password, BeyondTrust and Cloudflare.
- Salesloft Drift, August 2025. Drift is a chatbot many companies connected to their Salesforce. An attacker Google tracks as UNC6395 stole Drift's OAuth tokens and used them to export data from the Salesforce accounts of more than 700 organisations, including Cloudflare, Zscaler and Palo Alto Networks. The attackers then searched the exported data for AWS keys, passwords and Snowflake tokens that customers had pasted into support cases.
- ChainDrop, August 2026. The npm worm in Poisoned packages read tokens from developer machines and CI runners, including GitHub, npm and cloud tokens, and used each one straight away to reach the next target.
Why it keeps working
- A token is a bearer pass. Most tokens work for anyone who presents them, from anywhere.
- Tokens live too long. OAuth refresh tokens for integrations can stay valid for months.
- Integrations get broad scopes. "Full access" is the default button, so a chatbot ends up able to export the whole customer database.
- Nobody reviews connected apps. Companies forget what they connected years ago, and those tokens keep working.
- Secrets end up in data. Support tickets, chat messages and logs collect keys that were never meant to be stored there.
How to do it
1. Short-lived sessions, invalidated on change
Sessions expire. Signing out, changing a password or removing a user ends every session for that account on the server, not just in one browser.
2. Cookies scripts cannot read
Set-Cookie: session=…; HttpOnly; Secure; SameSite=Lax; Path=/HttpOnly keeps the cookie away from JavaScript, so an injected script cannot copy it. It does not stop malware on the machine, which reads the browser's files directly.
3. Bind sessions where you can
Newer browsers support Device Bound Session Credentials, which tie a session to a key kept in the device's hardware, so a copied cookie does not work elsewhere. Where that is not available, re-check the user when a session suddenly changes country, device or network.
4. Give integrations the least they need
- Grant read-only scopes when an app only reads.
- Limit it to the objects it needs, not the whole account.
- Review connected apps every quarter and remove what nobody uses.
- Watch for bulk exports by integration accounts.
5. Never paste secrets into tickets or chats
Scan support tickets and logs for things that look like keys, and redact them. When one is found, rotate it; assume it was read.
6. Scrub debug files
Before sending a HAR file to anyone, remove the Cookie and Authorization headers. Many tools now offer a "sanitised HAR" export.
How we do it here
Session cookies are HttpOnly, Secure and SameSite=Lax, signed on the server, and carry their own expiry, so a copied cookie stops working when it runs out. Access is checked on every request against the current state of the account, so a removed user loses access on their next request rather than when their cookie expires.
Benefits
- Short expiry puts a hard limit on what any stolen token is worth.
- Narrow scopes turn a breached integration into a small leak instead of a total one.
- Server-side checks mean revoking access actually revokes it.
Disadvantages
- Short sessions mean more sign-ins, which users dislike.
- Device-bound sessions are new and not supported everywhere yet.
- Narrow scopes break integrations when their needs change, and someone has to maintain them.
- Nothing here helps once malware is running on the user's own machine and using the session live.
Checklist
- Sessions expire and can be ended on the server.
- Session cookies are
HttpOnlyandSecure. - Connected apps have the narrowest scopes that work, and are reviewed regularly.
- Bulk exports by integrations raise an alert.
- Tickets, chats and logs are scanned for secrets.
- HAR files are sanitised before they are shared.
Sources
- Google Cloud — Widespread data theft targets Salesforce instances via Salesloft Drift
- Chrome for Developers — Device Bound Session Credentials
- OWASP — Session Management Cheat Sheet
- Okta, Unauthorized access to Okta's support case management system: root cause and remediation, November 2023.
- Linus Media Group, statement on the channel takeover, March 2023.