Google DevSite RCE: How a leaked secret enabled remote code execution
A researcher found a critical vulnerability in Google's DevSite platform where an OAuth client secret was used to sign session cookies, enabling remote code execution across multiple domains.
Security researcher Simon Koeck discovered a critical remote code execution (RCE) vulnerability in Google’s shared DevSite platform in August 2026. The flaw allowed an attacker to execute arbitrary code on servers hosting developer documentation for services like Firebase and Android by exploiting a misconfigured Flask session cookie. Google awarded Koeck $90,000 for the report after confirming the issue affected multiple high-profile subdomains.
What happened
Koeck was mapping the OAuth authentication flow used across Google’s developer documentation sites, including developers.google.com. He noticed that the Flask session cookie issued during the OAuth handshake was unusually large, around 1,200 bytes. Since Flask cookies are signed but not encrypted, he decoded the payload to inspect its contents. Inside, he found a pickle-serialized object containing an oauth2client.client.OAuth2WebServerFlow instance. Crucially, this object held the Google OAuth client_id and client_secret in plaintext.
The presence of the client secret in a client-side cookie was already a significant security finding. However, Koeck realized the implications went further when he tested whether this secret was also used as the Flask SECRET_KEY for signing the cookie itself. By deriving the signing key from the exposed client secret using Flask’s standard itsdangerous library logic, he successfully reproduced the cookie’s signature offline. This meant the server was using a secret stored inside the very data it was trying to protect to verify that data’s integrity.
With the ability to forge valid session signatures, Koeck could bypass the intended security controls. The application logic retrieved the OAuth flow object from the session and deserialized it using pickle.loads(). Because Python’s pickle module can execute arbitrary code during deserialization if it encounters specific opcodes, and because Koeck could now create validly signed cookies, he had achieved unauthenticated remote code execution. He demonstrated this by injecting payloads that caused the server to sleep for specific durations, proving the code was executing on the backend without accessing sensitive production data.
How it works
The vulnerability relied on a chain of three specific misconfigurations. First, the application stored sensitive credentials (the OAuth client secret) directly in the user’s session cookie. Second, it used that same client secret as the cryptographic key to sign the session cookie, creating a circular dependency where the key was public to anyone who inspected the cookie. Third, the application deserialized user-controlled data from the cookie using Python’s pickle module, which is inherently unsafe for untrusted input because it allows object instantiation and method calls during the loading process.
Flask uses the itsdangerous library to sign cookies, typically deriving a specific signing key from the main SECRET_KEY using HMAC-SHA1. Koeck replicated this derivation locally using the leaked client secret. Once he confirmed the signature matched, he crafted a new session cookie. He inserted a malicious pickle payload under the expected session key, signed it with the derived key, and sent it to the server. The server verified the signature successfully, extracted the pickle, and executed the embedded instructions, such as calling time.sleep().
Key details
- The vulnerability existed in the shared DevSite platform, affecting
developers.google.com,firebase.google.com,developer.android.com,source.android.com, anddocs.partner.android.com. - The Flask session cookie contained a pickle-serialized
OAuth2WebServerFlowobject with the live OAuthclient_secretin plaintext. - The OAuth
client_secretwas used as the FlaskSECRET_KEYto sign the session cookie, allowing attackers to forge valid sessions. - Remote code execution was proven using
time.sleep(N)payloads, where server response times matched the injected sleep duration exactly. - Google classified the issue as S0 (critical) RCE and awarded a $90,000 bounty, calculated as a $75,000 base plus a 1.2x multiplier for report quality.
- The fix involved rotating secrets, separating signing keys from OAuth credentials, storing flow objects server-side, and replacing pickle with a safe data format.
Why it matters
This incident highlights the dangers of using complex serialization formats like pickle for data that crosses trust boundaries. While pickle is convenient for preserving Python object state, it provides no mechanism to restrict which classes or functions can be invoked during deserialization. When combined with a compromised signing key, it becomes a direct path to remote code execution. Developers often assume that signed cookies are tamper-proof, but if the signing key is leaked or poorly managed, that guarantee vanishes entirely.
For engineering teams, this serves as a reminder to audit how secrets are managed and rotated. Using a credential for multiple purposes—such as both API authentication and session signing—increases the blast radius of a single leak. It also underscores the importance of keeping sensitive state server-side. Cookies should contain only opaque references or minimal, non-sensitive data, especially when dealing with authentication flows involving third-party providers like Google OAuth.
What you can do
- Audit your application’s session management to ensure signing keys are distinct from other credentials like API secrets or OAuth tokens.
- Replace
picklewith safe serialization formats like JSON or Protocol Buffers for any data that travels to the client or crosses trust boundaries. - Store sensitive state, such as OAuth flow objects, in server-side sessions or caches rather than in client-side cookies.
- Implement strict content security policies and monitor for unusual latency patterns that might indicate time-based blind RCE attempts.
- Rotate all exposed secrets immediately if a leak is suspected and invalidate existing sessions signed with those keys.
- Use static analysis tools to detect the use of unsafe deserialization methods like
pickle.loads()on untrusted input.



