
Here's the uncomfortable truth: every time your application integrates with Google, Microsoft, or Salesforce on behalf of users, you're creating a backdoor that could persist indefinitely. Unlike session tokens that expire, OAuth refresh tokens live forever unless explicitly revoked—and most organizations have no idea they exist.
The scale of this blind spot is staggering. Recent data shows that 80% of security leaders recognize unmanaged OAuth grants as critical risks, yet 45% of organizations are doing absolutely nothing to monitor them. The remaining third? They're tracking these persistent access tokens in spreadsheets.
The Perfect Storm: How UNC6395 Exploited This Gap
This isn't theoretical. The threat group UNC6395 recently demonstrated exactly how dangerous this oversight can be. They obtained valid OAuth refresh tokens (likely through phishing) and used them to access Salesforce environments across over 700 organizations through Drift, a sales engagement platform.
What made this attack so effective? The tokens bypassed every traditional security control:
- No multi-factor authentication required
- No perimeter detection
- No session timeouts
- No automatic cleanup
<> "Your perimeter controls don't see it. Your MFA doesn't stop it. And in most organizations, no one is watching it."/>
The attackers essentially had persistent, invisible access to hundreds of Salesforce instances—the kind of access that takes months to discover through traditional monitoring.
Why Developers Are Inadvertently Creating This Problem
If you're building integrations, you're likely contributing to this attack surface without realizing it. Here's a typical OAuth implementation that creates persistent tokens:
1// Standard OAuth flow - creates indefinite refresh token
2async function handleOAuthCallback(code) {
3 const tokenResponse = await fetch('https://oauth2.googleapis.com/token', {
4 method: 'POST',
5 body: new URLSearchParams({
6 code,
7 client_id: process.env.GOOGLE_CLIENT_ID,
8 client_secret: process.env.GOOGLE_CLIENT_SECRET,That refresh_token can be used to generate new access tokens indefinitely. If an attacker obtains it—through a database breach, phishing, or insider threat—they have persistent access that survives password resets, MFA changes, and most security reviews.
The Detection Gap That's Killing Visibility
Traditional security tools weren't designed for this threat model. They monitor network perimeters, endpoints, and user sessions—but OAuth tokens operate in the spaces between these controls.
Consider what happens when an attacker uses a stolen OAuth token:
1# Attacker uses stolen refresh token
2def use_stolen_token(refresh_token):
3 # Generates fresh access token - looks legitimate
4 access_token = refresh_oauth_token(refresh_token)
5
6 # API calls appear normal - authorized user, valid token
7 data = make_api_call(access_token, '/sensitive-data')
8
9 # No unusual login, no MFA bypass alerts, no perimeter breach
10 return dataFrom the API provider's perspective, these requests look perfectly legitimate. The token is valid, the permissions were properly granted, and the user account exists. There's no "break-in" to detect.
Building Defense Into Your Integration Architecture
The solution isn't to avoid OAuth—it's to implement it defensively. Here's how to reduce the attack surface:
Implement Token Rotation Policies
1interface TokenManager {
2 async rotateTokens(userId: string): Promise<void> {
3 const currentTokens = await this.getTokens(userId);
4
5 // Force re-authentication every 90 days
6 if (this.isTokenStale(currentTokens, 90)) {
7 await this.revokeTokens(currentTokens);
8 throw new TokenExpiredError('Re-authentication required');Request Minimal Scopes
Don't request https://www.googleapis.com/auth/drive when you only need read access to specific files. Attackers inherit whatever permissions you requested.
1// Bad: Excessive scope
2const authUrl = `https://accounts.google.com/oauth/authorize?
3 scope=https://www.googleapis.com/auth/drive&
4 response_type=code&client_id=${clientId}`;
5
6// Good: Minimal scope
7const authUrl = `https://accounts.google.com/oauth/authorize?
8 scope=https://www.googleapis.com/auth/drive.readonly&
9 response_type=code&client_id=${clientId}`;Implement Usage Monitoring
Log token usage patterns so customers can detect anomalous access:
1interface TokenAuditLog {
2 tokenId: string;
3 userId: string;
4 action: 'created' | 'used' | 'refreshed' | 'revoked';
5 ipAddress: string;
6 userAgent: string;
7 timestamp: Date;
8 apiEndpoint?: string;
9}Why This Matters Beyond Your Application
This vulnerability represents a fundamental shift in how attackers operate. Traditional breaches focused on stealing data—OAuth token compromise focuses on maintaining access. An attacker with persistent OAuth tokens can:
- Survive incident response efforts
- Access new data as it's created
- Pivot between integrated systems
- Remain undetected for months or years
The Drift incident affecting 700+ organizations shows this isn't a targeted attack—it's a scalable technique that works across entire customer bases.
Your next steps:
1. Audit your OAuth implementations for indefinite token lifespans
2. Implement token rotation policies that force periodic re-authentication
3. Document the tokens your application creates so customers can inventory them
4. Add usage logging that enables anomaly detection
5. Review your scope requests and minimize permissions
The uncomfortable reality is that every integration you build potentially creates a backdoor into your customers' environments. The question isn't whether attackers will exploit OAuth tokens—it's whether you'll build defensively enough to make their job harder.

