News

Google Paid $90,000 After Its DevSite Signed Sessions With an OAuth Secret Stuck Inside the Cookie

Google's DevSite developer portals signed Flask session cookies with an OAuth client secret that sat in plaintext inside the cookie, letting anyone forge sessions and reach remote code execution. Researcher Simon Koeck earned $90,000; Google fixed it on October 7.

Google Paid $90,000 After Its DevSite Signed Sessions With an OAuth Secret Stuck Inside the Cookie

Google has paid security researcher Simon Koeck $90,000 for a bug that let anyone on the internet run code on the servers behind its developer documentation sites. No account, no login, no phishing. The key needed to pull it off was handed to every visitor inside their own browser cookie.

Koeck published his writeup on October 12, five days after Google shipped a fix. The flaw sat in DevSite, the platform that powers developers.google.com, and it reached across several of Google's best known developer domains.

The key was in the lock

Koeck started at the OAuth sign-in flow on developers.google.com. Visiting the authorize endpoint set a Flask session cookie and bounced the browser to Google's login page. Nobody had to actually sign in for the cookie to appear.

Flask session cookies are signed, not encrypted, so anyone can read what is inside them. This one was about 1,200 bytes and held a CSRF token plus a serialized OAuth flow object. That object contained the OAuth client ID and the client secret, in plaintext.

The secret turned out to be doing a second job. DevSite was also using it as the Flask secret key that signs the session cookie. When Koeck recomputed the cookie's signature with that secret, it matched. Anyone who decoded a single cookie could therefore write any session data they liked and sign it so the server would trust it.

From a forged cookie to code execution

A forged session alone would be bad. What made it critical was where that session data went next. When a user returned from Google sign-in, the callback pulled the OAuth flow object out of the session and deserialized it with Python's pickle module, which can execute code while it loads data.

Put together, an attacker controls the cookie, the cookie controls what gets unpickled, and the unpickling controls the server. That is unauthenticated remote code execution.

Koeck proved it without running anything harmful. He made the server pause for a chosen number of seconds and showed that response times tracked his input across 0, 3, 5 and 8 seconds. His control tests behaved as expected: no cookie, a tampered signature or a missing flow entry all produced "Invalid request" errors, while a genuine flow reached the token exchange and failed later on a fake authorization code.

The same signing key and session pattern worked on firebase.google.com, developer.android.com, source.android.com and docs.partner.android.com. The writeup does not report any exploitation in the wild, and no CVE was assigned.

A fast payout, a slower fix

Koeck submitted the report on August 6. Google triaged and accepted it the next day and settled the reward on August 27. The fix landed on October 7.

The bounty was classed as an S0 remote code execution in Normal Google Applications, worth a $75,000 base. Google added a 1.2 multiplier for exceptional report quality, bringing it to $90,000.

The remedy Koeck lays out is the standard one. Rotate the exposed OAuth client secrets and invalidate every session signed with them. Give each deployment its own high-entropy Flask secret key that has nothing to do with OAuth credentials. Keep the OAuth flow on the server and hand the browser only an opaque reference. And stop passing pickle data across a boundary the client can touch.

None of this is exotic. Reusing one secret for two jobs and then trusting a cookie with it is the same family of mistake behind smaller incidents, like the hardcoded session secret that let researchers impersonate 95 users. The difference here is that it ran on Google's own front door for developers.

Some offers on this page may be paid placements or contain affiliate links.

Cyberpresso: daily cyber & AI brief

Free daily newsletter, read in 5 minutes.

Subscribe free