How I Found a $90,000 Remote Code Execution Vulnerability in Google
Simon Koeck
A researcher turned one Google login cookie into remote code execution. The bug paid $90,000 and came from leaking a secret into the thing it was meant to protect.
Based on reporting by Simon Koeck — read the original for the full story.
Summary, retelling and take written by AI under human oversight; images are AI-generated illustrations. How we work · Report an error
A security researcher found a remote code execution bug in Google’s developer sites by staring at the cookie created during an OAuth redirect. The flow was simple: hit /oauth2authorize, get a Flask session cookie, and get sent to Google’s sign-in page. No account was needed. The cookie just looked unusually large, so he decoded it.
That’s where things got ugly. Flask session cookies are signed, not encrypted, so the contents were readable. Inside the session sat a Google OAuth flow object, and inside that object were two things that should never have been sitting in a client-side cookie at all: an OAuth client_id and a client_secret. The secret was live at the time of writing, and the researcher found that the same secret also worked as the Flask signing key.
He didn’t stop at a hunch. Using Flask’s normal cookie-session derivation, he recomputed the cookie signature offline and got a byte-for-byte match. Flip one character in the signature and the server rejected it. Re-sign the payload with the recovered secret and the server accepted it. That meant session integrity was gone. Anyone who could obtain the cookie could forge it.
The callback logic made that fatal. After verifying the cookie, the app pulled the OAuth flow back out of the session, base64-decoded a bytes field, and passed the result to pickle.loads. Pickle is fine only when the sender is trusted. Here, the sender wasn’t trusted anymore. The researcher built his own session, chose his own CSRF token, and planted his own pickle payload under the matching session key.
He proved execution without running commands on Google’s systems. Instead, he used payloads that called time.sleep for different lengths and watched the response times line up: 0 seconds, about 0.2 seconds; 3 seconds, about 3.2; 5 seconds, about 5.2; 8 seconds, about 8.3. He also tested other DevSite hosts, including firebase.google.com, developer.android.com, source.android.com, and docs.partner.android.com. Google paid $90,000: a $75,000 base reward plus a 1.2 multiplier for report quality.
My take — AI-written commentary, not fact-checked reporting
Pickle in a client boundary is the security version of leaving your keys in the front door. The real embarrassment here isn’t just the RCE; it’s that one secret was doing two jobs and both jobs were public-facing by accident. This is why boring server-side state and dull data formats keep winning while clever shortcuts keep writing incident reports.
Read more about this at: Simon Koeck