A Flask Cookie Signed With a Leaked OAuth Secret Gave Researcher Code Execution on Google DevSite
Security / news
A Flask Cookie Signed With a Leaked OAuth Secret Gave Researcher Code Execution on Google DevSite
Simon Koeck's writeup says an anonymous request to an OAuth endpoint was enough to forge a session that reached pickle.loads(); Google fixed it on October 7 and paid $90,000.

An unauthenticated attacker could run code on Google's DevSite documentation platform by forging a Flask session cookie, provided the OAuth client secret that signed it was still live, according to a writeup published October 12, 2026 by researcher Simon Koeck. Google paid $90,000 and fixed the flaw on October 7. No CVE has been assigned, and the writeup does not mention one.
What the bug was
Koeck wrote that the /oauth2authorize endpoint on DevSite set a Flask session cookie holding a pickled object. That object contained Google's OAuth client_id and client_secret in plaintext. Flask session cookies are signed, not encrypted, so anyone who requested the cookie could decode it and read the secret.
The second half of the chain is that the same client secret doubled as the Flask SECRET_KEY. Flask's own API documentation says that when a secret key is set, "cryptographic components can use this to sign cookies and other things". A reader of the cookie therefore held the signing key and could mint valid sessions.
The OAuth callback then passed a value from the session to pickle.loads(). The Python documentation warns that the pickle module "is not secure" and that malicious data can "execute arbitrary code during unpickling". It suggests signing data with hmac to detect tampering, which is what the signature on a Flask cookie does. That protection fails when the key is public. Koeck described the sink as only safe "as long as nobody else can forge a valid cookie".
Preconditions and proof
No Google account was needed, because the endpoint issued the cookie to any anonymous requester. Koeck wrote that the secret "was still live at the time of writing".
He wrote that he did not run commands on production systems. Instead, a forged session produced a server response delay matching a chosen sleep duration, while a missing cookie, a bad signature and a missing flow entry behaved as controls. That demonstrates execution timing without touching data.
The writeup lists five domains where the leaked key verified sessions: developers.google.com, firebase.google.com, developer.android.com, source.android.com and docs.partner.android.com. Its headline refers to seven domains, and it does not explain the gap.
Timeline and payout
| Date (2026) | Event |
|---|---|
| August 6, 22:48 | Report submitted |
| August 7, 08:12 | Triaged |
| August 7, 16:23 | Accepted |
| August 27 | Reward decided |
| October 7, 15:20 | Fixed |
| October 12 | Writeup published |
The reward was $75,000 for a remote code execution on a Normal Google Application (tier T2, severity S0), multiplied by 1.2 for report quality, which gives $90,000. Those categories and the multiplier come from Koeck's account; this site did not retrieve Google's rules page.
- Accepted1 days
- Reward decided21 days
- Fixed62 days
Source: Simon Koeck writeup timeline, accessed 2026-10-12
The score here is not a number at all: the writeup gives a severity label (S0) but no CVSS vector. The writeup does not say whether the secrets were rotated before October 7, so the 62 days from report to fix is the only remediation figure available.

What Google has and has not said
The only direct line from Google in the writeup is Koeck's own acknowledgement: "Thanks to the Google Bug Hunters team and the DevSite engineers for investigating and fixing this issue." The writeup does not say which of Koeck's four proposed fixes Google adopted. They were rotating both exposed client secrets, using a unique SECRET_KEY per deployment, keeping OAuth flow state on the server, and dropping pickle for data that crosses a client boundary.
There is no evidence in any source read for this story of exploitation by anyone other than the researcher. Anyone running Flask should check that the SECRET_KEY is not reused as another credential, and that nothing user-controlled reaches pickle.loads(). For related coverage, see Zammad's two CVEs added to CISA's catalogue and the OpenPDC and openHistorian advisory.
Sources
More in Security
- 01Ledger Confirms an Implant in a Nano X Sold Through CryptoBilis, but Not That It Caused the TheftsLedger said on October 10 that one affected customer's wallet held an unauthorized hardware implant. It has not said how many devices are modified or how the losses happened.
- 02Ivanti Connect Secure Chain Gives Root on Patched Appliances, and One Link Still Has No FixVolexity says an actor it calls UTA0576 chained three flaws from October 3. Ivanti patched two on October 13 and has not scheduled the third beyond "the coming weeks".
- 03SonicWall SMA1000 CVSS 10.0 Flaw Draws 135 Attempts From Two IP AddressesPrevidian's telemetry comes from a single sensor, and SonicWall had not updated advisory SNWLID-2026-0017 to mention exploitation when The Hacker News reported on Oct. 12.
- 04Seven Nations Name Integrity Tech Behind Flax Typhoon Tools as FBI Seizes Seven DomainsAdvisory AA26-281A lists eight exploited CVEs dating to 2014, and five of them were added to CISA's KEV catalog only with its release.