Claude Code: Hunting Account Takeover Vulnerabilities in Granola
Security flaws in modern AI-integrated apps usually hide in the way they handle session tokens or third-party authentication. I managed to find a one-click account takeover (ATO) in Granola that also granted access to the user's webcam—a pretty massive privacy leak for a productivity tool.
The Vulnerability Path
The issue stemmed from a flawed implementation of the OAuth flow combined with improper session validation. Essentially, the application didn't strictly verify the state parameter during the callback, allowing an attacker to craft a malicious link that forced a victim to link their account to the attacker's identity.
To replicate this as a real-world AI workflow for security testing, I used a combination of manual interception and some custom scripts to automate the request forging.
1. Capture the Auth Request: I monitored the network traffic during a standard login. I noticed the code and state parameters were being passed back to the redirect URI without sufficient cryptographic binding to the original user session.
2. Craft the Payload: By manipulating the callback URL, I could essentially "swap" the authentication context.
3. The Trigger: Once the victim clicked the crafted link, the session was hijacked. Because Granola requests webcam permissions for its core functionality (transcribing/recording meetings), the hijacked session inherited those active permissions.
Technical Breakdown
If you're doing a deep dive into LLM agent security or general app deployment, this is a classic example of why "trusting the client" is a mistake. The logic looked something like this in the backend:
// Hypothetical flawed logic
app.get('/auth/callback', async (req, res) => {
const { code, state } = req.query;
const token = await exchangeCodeForToken(code);
// Problem: No verification that 'state' matches the session that initiated the request
const user = await findUserByToken(token);
req.session.userId = user.id;
res.redirect('/dashboard');
});
By bypassing the state check, the attacker controls who is logged into the current browser session.
Impact and Fixes
The fallout here is significant. Beyond just seeing a user's notes, the webcam access means an attacker could potentially trigger recordings or capture images without the user realizing the session had been compromised.
For anyone building an AI workflow or a SaaS app from scratch, here is the practical tutorial for preventing this:
- Strict State Validation: Always generate a high-entropy random string for the
stateparameter, store it in a secure, HTTP-only cookie, and verify it matches the callback exactly. - PKCE Implementation: Use Proof Key for Code Exchange (PKCE) even for server-side apps to ensure the entity requesting the token is the same one that started the flow.
- Permission Scoping: Don't grant "blanket" permissions. Request webcam access only at the moment of recording, rather than maintaining a persistent open door.
All Replies (3)
Curious if you tested for session token leaks in the referer headers during the hunt?
That OAuth callback flaw sounds familiar. Which specific tool did you use to find the misconfiguration last year?
Found the Granola security docs! Has anyone actually checked if their data handling policies hold up for corporate use?