Google has corrected a critical vulnerability chain in its shared DevSite platform that could have allowed an unauthenticated attacker to execute code on multiple developer-focused web properties. The weakness combined exposed OAuth material, reuse of a secret key and unsafe Python deserialization, turning a seemingly ordinary session cookie into a route toward server compromise.
The affected platform supported sites including developers.google.com, firebase.google.com, developer.android.com, source.android.com and docs.partner.android.com. Researcher Simon Koeck reported the issue in August, and Google reportedly completed its fix on October 7, 2026. The company’s Vulnerability Reward Program paid a $90,000 bounty.
A readable cookie exposed the key protecting it
The chain began at a DevSite OAuth endpoint that issued a Flask session cookie. Flask’s default client-side sessions are signed to prevent undetected modification, but their contents are not encrypted. A user can inspect the stored data even though changing it should invalidate the signature.
After decompressing and decoding the cookie, the researcher found that it contained a serialized OAuth flow object, including a Google OAuth client ID and client secret. The crucial discovery was that the OAuth client secret was also being used as the Flask application’s session-signing key.
This amounted to putting the verification secret inside the object it was supposed to protect. Anyone who obtained a cookie could recover that key, alter session values and create a new signature that the server would accept as authentic. Because the OAuth authorization endpoint was reachable without a Google account, acquiring the starting cookie did not require an authenticated user.
Unsafe deserialization completed the RCE chain
Forging a trusted session was serious, but another design choice converted it into remote code execution. During the OAuth callback, the application reportedly Base64-decoded an OAuth flow object stored in the session and passed the result to Python’s pickle.loads().
Python’s pickle format can reconstruct complex objects, and that process may invoke functions. It is therefore unsafe for any data an attacker can influence. With the signing key in hand, an attacker could build a session containing a malicious pickle payload, sign it correctly and send it through the callback. The application would accept the cookie and deserialize the attacker-controlled object.
Koeck avoided running operating-system commands against Google’s infrastructure. Instead, the proof of concept used a harmless delay: requests paused for the precise number of seconds encoded in the payload. That behavior demonstrated that the selected Python function had executed while minimizing impact.
Shared infrastructure magnified the risk
The finding affected a common DevSite service rather than a single isolated documentation page. Shared components improve consistency and maintenance, but a security defect can inherit the combined reach of every property using them. In this case, the potential target set included prominent Android, Firebase and Google developer resources.
The vulnerability also illustrates why individually familiar mistakes can become critical when chained. A client-readable cookie is normal for signed Flask sessions. An OAuth client secret must remain confidential, while key reuse weakens separation between trust domains. Finally, pickle assumes its input is trusted. When the secret leaked and enabled session forgery, that final assumption collapsed.
Google’s fixes and lessons for developers
The remediation reportedly included rotating the exposed OAuth client secrets, invalidating sessions signed with them, separating Flask signing keys from OAuth credentials and moving OAuth flow objects into server-side storage. A browser cookie can then contain only an opaque reference rather than the sensitive object itself.
Engineering teams can use the case as a practical review checklist:
- Never place credentials, signing keys or recoverable secret material in client-visible state, even when the container is signed.
- Use separate secrets for OAuth, session integrity and other security boundaries so a leak in one system does not unlock another.
- Avoid pickle and similar executable serialization formats for data influenced by browsers, users or partner integrations.
- Prefer data-only encodings such as JSON with strict schema and type validation.
- After key exposure, rotate the secret and invalidate artifacts that were signed or encrypted with the old value.
The incident shows that a valid cryptographic signature proves little if the signing key is disclosed to the same client. Trust also depends on keeping secrets out of observable state and ensuring that data processing cannot unexpectedly become code execution.
Leave a Reply
You must be logged in to post a comment.