I Found a $90k Remote Code Execution Vulnerability in Google
🇬🇧 English
A security researcher found a remote code execution vulnerability in Google's developer documentation sites. While mapping the OAuth flow shared across these sites, the researcher noticed that the /oauth2authorize endpoint set an unusually large Flask session cookie, about 1,200 bytes, far more than a CSRF token and return URL would require. Flask session cookies are signed but not encrypted, so the contents were readable by anyone holding one.
Decoding the cookie revealed a pickle-serialized object containing Google's OAuth client_id and client_secret in plaintext. The researcher found that the client secret also served as the Flask SECRET_KEY, meaning the same value both held and verified the signature. Because the signing key was exposed inside the cookie itself, the researcher could recompute valid signatures offline and forge arbitrary session data.
The callback endpoint reads the OAuth flow data from the session and passes it to pickle.loads. With a forged session, an attacker could supply a malicious pickle payload, making this an unauthenticated remote code execution path. The researcher verified the issue safely by using a payload that only triggered time.sleep, avoiding any commands on Google's production systems.
The finding illustrates how storing secrets in client-side session data, and deserializing untrusted pickle data, can compound into a critical vulnerability. The bug earned a $90,000 bounty.
🇸🇦 العربية
كيف وجدت ثغرة تنفيذ تعليمات برمجية عن بُعد بقيمة 90,000 دولار في Google
اكتشف باحث أمني ثغرة تنفيذ تعليمات برمجية عن بُعد في مواقع توثيق المطورين لدى Google. وأثناء رسم خريطة لتدفق OAuth المشترك بين هذه المواقع، لاحظ الباحث أن نقطة النهاية /oauth2authorize تُعيّن ملف تعريف ارتباط جلسة Flask كبيرًا بشكل غير معتاد، يبلغ نحو 1,200 بايت، وهو أكبر بكثير مما يتطلبه رمز CSRF وعنوان URL الخاص بالعودة. ملفات تعريف ارتباط جلسات Flask موقّعة لكنها غير مشفّرة، لذا كان محتواها قابلًا للقراءة من أي شخص يحمل أحدها.
كشف فك ترميز ملف تعريف الارتباط عن كائن مُسلسَل بواسطة pickle يحتوي على client_id وclient_secret الخاصين بـ OAuth لدى Google بنص واضح. ووجد الباحث أن client secret كان يُستخدم أيضًا كمفتاح SECRET_KEY في Flask، أي أن القيمة نفسها تحفظ التوقيع وتتحقق منه. ولأن مفتاح التوقيع كان مكشوفًا داخل ملف تعريف الارتباط نفسه، تمكّن الباحث من إعادة حساب توقيعات صالحة دون اتصال بالإنترنت، وتزوير بيانات جلسة تعسفية.
تقرأ نقطة نهاية الاستدعاء بيانات تدفق OAuth من الجلسة وتمررها إلى pickle.loads. وباستخدام جلسة مزوّرة، كان بإمكان المهاجم تقديم حمولة pickle خبيثة، مما يجعل ذلك مسارًا لتنفيذ تعليمات برمجية عن بُعد دون مصادقة. وتحقق الباحث من المشكلة بأمان باستخدام حمولة تُفعّل فقط time.sleep، متجنبًا تنفيذ أي أوامر على أنظمة Google الإنتاجية.
يوضح هذا الاكتشاف كيف يمكن لتخزين الأسرار في بيانات الجلسة على جانب العميل، وإلغاء تسلسل بيانات pickle غير الموثوقة، أن يتراكما ليشكّلا ثغرة حرجة. وقد نالت هذه الثغرة مكافأة قدرها 90,000 دولار.
🇧🇩 বাংলা
Google-এ ৯০,০০০ ডলারের রিমোট কোড এক্সিকিউশন দুর্বলতা কীভাবে খুঁজে পেলাম
এক নিরাপত্তা গবেষক Google-এর ডেভেলপার ডকুমেন্টেশন সাইটে একটি রিমোট কোড এক্সিকিউশন দুর্বলতা খুঁজে পান। এই সাইটগুলোর মধ্যে ভাগ করা OAuth ফ্লো ম্যাপ করার সময় গবেষক লক্ষ্য করেন যে /oauth2authorize এন্ডপয়েন্ট একটি অস্বাভাবিকভাবে বড় Flask সেশন কুকি সেট করছে, প্রায় ১,২০০ বাইট, যা একটি CSRF টোকেন ও রিটার্ন URL-এর জন্য প্রয়োজনের তুলনায় অনেক বেশি। Flask সেশন কুকি স্বাক্ষরিত থাকে কিন্তু এনক্রিপ্ট করা থাকে না, তাই যার কাছে কুকি আছে সে এর বিষয়বস্তু পড়তে পারত।
কুকি ডিকোড করে গবেষক একটি pickle-সিরিয়ালাইজড অবজেক্ট পান, যাতে Google-এর OAuth client_id ও client_secret সাদা লেখায় ছিল। তিনি দেখেন যে client secret-ই Flask-এর SECRET_KEY হিসেবেও ব্যবহৃত হচ্ছিল, অর্থাৎ একই মান স্বাক্ষর ধারণ ও যাচাই দুটোই করত। স্বাক্ষরের কী কুকির ভেতরেই প্রকাশিত থাকায় গবেষক অফলাইনে বৈধ স্বাক্ষর পুনর্গণনা করে যেকোনো সেশন ডেটা জাল করতে পারতেন।
কলব্যাক এন্ডপয়েন্ট সেশন থেকে OAuth ফ্লো ডেটা পড়ে pickle.loads-এ পাঠায়। জাল সেশনের মাধ্যমে একজন আক্রমণকারী একটি ক্ষতিকর pickle পেলোড সরবরাহ করতে পারত, যা এটিকে প্রমাণীকরণবিহীন রিমোট কোড এক্সিকিউশন পথে পরিণত করত। গবেষক শুধু time.sleep চালু করে এমন একটি পেলোড ব্যবহার করে নিরাপদভাবে সমস্যাটি যাচাই করেন এবং Google-এর প্রোডাকশন সিস্টেমে কোনো কমান্ড চালানো এড়িয়ে যান।
এই আবিষ্কার দেখায় কীভাবে ক্লায়েন্ট-সাইড সেশন ডেটায় গোপন তথ্য সংরক্ষণ এবং অবিশ্বস্ত pickle ডেটা ডিসিরিয়ালাইজ করা একত্রে একটি গুরুতর দুর্বলতায় পরিণত হতে পারে। এই বাগের জন্য ৯০,০০০ ডলার পুরস্কার মিলেছে।
🇩🇪 Deutsch
Wie ich eine Remote-Code-Execution-Lücke bei Google im Wert von 90.000 $ fand
Ein Sicherheitsforscher entdeckte eine Remote-Code-Execution-Lücke auf den Entwickler-Dokumentationsseiten von Google. Beim Kartieren des OAuth-Ablaufs, der über diese Seiten hinweg geteilt wird, bemerkte der Forscher, dass der Endpunkt /oauth2authorize ein ungewöhnlich großes Flask-Session-Cookie setzte, etwa 1.200 Byte, weit mehr, als ein CSRF-Token und eine Rücksprung-URL benötigen. Flask-Session-Cookies sind signiert, aber nicht verschlüsselt, sodass ihr Inhalt von jedem gelesen werden konnte, der ein solches Cookie besaß.
Das Dekodieren des Cookies offenbarte ein pickle-serialisiertes Objekt, das Googles OAuth-client_id und client_secret im Klartext enthielt. Der Forscher stellte fest, dass das client secret zugleich als Flask-SECRET_KEY diente, das heißt, derselbe Wert hielt die Signatur und prüfte sie. Da der Signaturschlüssel im Cookie selbst offenlag, konnte der Forscher gültige Signaturen offline neu berechnen und beliebige Sitzungsdaten fälschen.
Der Callback-Endpunkt liest die OAuth-Ablaufdaten aus der Sitzung und übergibt sie an pickle.loads. Mit einer gefälschten Sitzung hätte ein Angreifer eine bösartige pickle-Nutzlast einschleusen können, was dies zu einem nicht authentifizierten Pfad für Remote Code Execution machte. Der Forscher verifizierte das Problem sicher mit einer Nutzlast, die lediglich time.sleep auslöste, und vermied so jegliche Befehle auf Googles Produktionssystemen.
Der Fund zeigt, wie die Speicherung von Geheimnissen in clientseitigen Sitzungsdaten und die Deserialisierung nicht vertrauenswürdiger pickle-Daten sich zu einer kritischen Schwachstelle verstärken können. Der Fehler brachte eine Prämie von 90.000 $ ein.
🇪🇸 Español
Cómo encontré una vulnerabilidad de ejecución remota de código de 90.000 dólares en Google
Un investigador de seguridad encontró una vulnerabilidad de ejecución remota de código en los sitios de documentación para desarrolladores de Google. Al analizar el flujo OAuth compartido entre estos sitios, el investigador notó que el endpoint /oauth2authorize establecía una cookie de sesión de Flask inusualmente grande, de unos 1.200 bytes, muy por encima de lo que requieren un token CSRF y una URL de retorno. Las cookies de sesión de Flask están firmadas pero no cifradas, por lo que su contenido era legible por cualquiera que tuviera una.
Al decodificar la cookie, el investigador encontró un objeto serializado con pickle que contenía el client_id y el client_secret de OAuth de Google en texto plano. Descubrió que el client secret también servía como SECRET_KEY de Flask, lo que significa que el mismo valor almacenaba y verificaba la firma. Como la clave de firma estaba expuesta dentro de la propia cookie, el investigador pudo recalcular firmas válidas sin conexión y falsificar datos de sesión arbitrarios.
El endpoint de callback lee los datos del flujo OAuth desde la sesión y los pasa a pickle.loads. Con una sesión falsificada, un atacante podía suministrar una carga maliciosa de pickle, convirtiendo esto en una ruta de ejecución remota de código sin autenticación. El investigador verificó el problema de forma segura usando una carga que solo activaba time.sleep, evitando ejecutar comandos en los sistemas de producción de Google.
El hallazgo ilustra cómo almacenar secretos en datos de sesión del lado del cliente y deserializar datos pickle no confiables pueden combinarse hasta convertirse en una vulnerabilidad crítica. El error obtuvo una recompensa de 90.000 dólares.
🇫🇷 Français
Comment j'ai trouvé une faille d'exécution de code à distance de 90 000 $ chez Google
Un chercheur en sécurité a découvert une faille d'exécution de code à distance dans les sites de documentation pour développeurs de Google. En cartographiant le flux OAuth partagé entre ces sites, le chercheur a remarqué que le point de terminaison /oauth2authorize définissait un cookie de session Flask anormalement volumineux, d'environ 1 200 octets, bien plus que ce qu'exigent un jeton CSRF et une URL de retour. Les cookies de session Flask sont signés mais non chiffrés : leur contenu était donc lisible par quiconque en possédait un.
Le décodage du cookie a révélé un objet sérialisé avec pickle contenant le client_id et le client_secret OAuth de Google en clair. Le chercheur a constaté que le client secret servait aussi de SECRET_KEY à Flask, ce qui signifie que la même valeur détenait et vérifiait la signature. Comme la clé de signature était exposée dans le cookie lui-même, le chercheur pouvait recalculer des signatures valides hors ligne et forger des données de session arbitraires.
Le point de terminaison de rappel lit les données du flux OAuth depuis la session et les transmet à pickle.loads. Avec une session forgée, un attaquant pouvait fournir une charge utile pickle malveillante, faisant de ce problème un chemin d'exécution de code à distance sans authentification. Le chercheur a vérifié la faille de manière sûre à l'aide d'une charge utile qui ne déclenchait que time.sleep, évitant toute commande sur les systèmes de production de Google.
Cette découverte illustre comment le stockage de secrets dans les données de session côté client et la désérialisation de données pickle non fiables peuvent se combiner en une vulnérabilité critique. La faille a valu une prime de 90 000 $.
🇮🇳 हिन्दी
मुझे Google में 90,000 डॉलर की रिमोट कोड एक्जीक्यूशन कमजोरी कैसे मिली
एक सुरक्षा शोधकर्ता को Google की डेवलपर दस्तावेज़ साइटों में एक रिमोट कोड एक्जीक्यूशन कमजोरी मिली। इन साइटों पर साझा OAuth फ़्लो का मानचित्रण करते समय शोधकर्ता ने देखा कि /oauth2authorize एंडपॉइंट एक असामान्य रूप से बड़ी Flask सेशन कुकी सेट कर रहा था, लगभग 1,200 बाइट्स, जो CSRF टोकन और रिटर्न URL के लिए आवश्यक आकार से कहीं अधिक था। Flask सेशन कुकीज़ पर हस्ताक्षर होते हैं लेकिन वे एन्क्रिप्टेड नहीं होतीं, इसलिए उनकी सामग्री किसी भी ऐसे व्यक्ति द्वारा पढ़ी जा सकती थी जिसके पास कुकी हो।
कुकी को डिकोड करने पर एक pickle-सीरियलाइज़्ड ऑब्जेक्ट मिला, जिसमें Google का OAuth client_id और client_secret सादे पाठ में थे। शोधकर्ता ने पाया कि client secret ही Flask के SECRET_KEY के रूप में भी काम करता था, यानी वही मान हस्ताक्षर को रखता और सत्यापित करता था। चूँकि हस्ताक्षर की कुंजी स्वयं कुकी के भीतर उजागर थी, शोधकर्ता ऑफ़लाइन वैध हस्ताक्षर दोबारा गणना कर सकता था और मनमाना सेशन डेटा जाली बना सकता था।
कॉलबैक एंडपॉइंट सेशन से OAuth फ़्लो डेटा पढ़ता है और उसे pickle.loads को देता है। जाली सेशन के साथ, एक हमलावर दुर्भावनापूर्ण pickle पेलोड दे सकता था, जिससे यह बिना प्रमाणीकरण वाला रिमोट कोड एक्जीक्यूशन मार्ग बन जाता। शोधकर्ता ने केवल time.sleep को सक्रिय करने वाले पेलोड का उपयोग करके इस समस्या को सुरक्षित रूप से सत्यापित किया, और Google के प्रोडक्शन सिस्टम पर कोई कमांड नहीं चलाई।
यह खोज दर्शाती है कि क्लाइंट-साइड सेशन डेटा में गुप्त जानकारी संग्रहीत करना और अविश्वसनीय pickle डेटा को डीसीरियलाइज़ करना मिलकर एक गंभीर कमजोरी का रूप ले सकते हैं। इस बग के लिए 90,000 डॉलर का इनाम मिला।
🇮🇩 Bahasa Indonesia
Cara Saya Menemukan Celah Eksekusi Kode Jarak Jauh Senilai $90.000 di Google
Seorang peneliti keamanan menemukan celah eksekusi kode jarak jauh di situs dokumentasi pengembang Google. Saat memetakan alur OAuth yang dipakai bersama di situs-situs ini, peneliti melihat bahwa endpoint /oauth2authorize menetapkan cookie sesi Flask yang sangat besar, sekitar 1.200 byte, jauh melebihi kebutuhan token CSRF dan URL pengembalian. Cookie sesi Flask ditandatangani tetapi tidak dienkripsi, sehingga isinya dapat dibaca oleh siapa pun yang memegangnya.
Saat cookie didekode, peneliti menemukan objek hasil serialisasi pickle yang berisi client_id dan client_secret OAuth milik Google dalam teks biasa. Peneliti juga mendapati bahwa client secret digunakan sebagai SECRET_KEY Flask, yang berarti nilai yang sama digunakan untuk membuat dan memverifikasi tanda tangan. Karena kunci penandatanganan terekspos di dalam cookie itu sendiri, peneliti dapat menghitung ulang tanda tangan yang valid secara offline dan memalsukan data sesi sembarang.
Endpoint callback membaca data alur OAuth dari sesi dan meneruskannya ke pickle.loads. Dengan sesi palsu, penyerang dapat memasukkan muatan pickle berbahaya, sehingga ini menjadi jalur eksekusi kode jarak jauh tanpa autentikasi. Peneliti memverifikasi masalah ini dengan aman menggunakan muatan yang hanya memicu time.sleep, sehingga tidak menjalankan perintah apa pun pada sistem produksi Google.
Temuan ini memperlihatkan bagaimana menyimpan rahasia dalam data sesi sisi klien dan mendeserialisasi data pickle yang tidak tepercaya dapat saling memperkuat menjadi celah kritis. Bug ini mendapat hadiah $90.000.
🇯🇵 日本語
Googleで9万ドルのリモートコード実行の脆弱性を見つけた方法
セキュリティ研究者が、Googleの開発者向けドキュメントサイトにおけるリモートコード実行の脆弱性を発見しました。これらのサイトで共有されているOAuthフローを調べていたところ、研究者は /oauth2authorize エンドポイントが、CSRFトークンやリターンURLに必要な量をはるかに超える、約1,200バイトという異常に大きなFlaskセッションCookieを設定していることに気づきました。FlaskのセッションCookieは署名されていますが暗号化されていないため、Cookieを持つ者なら誰でも中身を読むことができました。
Cookieをデコードすると、GoogleのOAuth client_idとclient_secretが平文で含まれた、pickleでシリアル化されたオブジェクトが見つかりました。さらに研究者は、client secretがFlaskのSECRET_KEYとしても使われていたことを発見しました。つまり同じ値が署名の生成と検証の両方を担っていたのです。署名鍵がCookie自体の中で露出していたため、研究者はオフラインで有効な署名を再計算し、任意のセッションデータを偽造できました。
コールバックエンドポイントはセッションからOAuthフローのデータを読み取り、それを pickle.loads に渡します。偽造したセッションがあれば、攻撃者は悪意のあるpickleペイロードを供給でき、これは認証不要のリモートコード実行経路となりえました。研究者は、time.sleepを呼び出すだけのペイロードを用いて安全に問題を検証し、Googleの本番システム上でコマンドを実行することは避けました。
この発見は、クライアント側のセッションデータに秘密情報を保存することと、信頼できないpickleデータを逆シリアル化することが組み合わさると、重大な脆弱性に発展しうることを示しています。このバグには9万ドルの報奨金が支払われました。
🇧🇷 Português
Como encontrei uma vulnerabilidade de execução remota de código de US$ 90 mil no Google
Um pesquisador de segurança encontrou uma vulnerabilidade de execução remota de código nos sites de documentação para desenvolvedores do Google. Ao mapear o fluxo OAuth compartilhado entre esses sites, o pesquisador notou que o endpoint /oauth2authorize definia um cookie de sessão Flask incomumente grande, de cerca de 1.200 bytes, muito mais do que um token CSRF e uma URL de retorno exigiriam. Os cookies de sessão do Flask são assinados, mas não criptografados, então seu conteúdo podia ser lido por qualquer pessoa que tivesse um deles.
Ao decodificar o cookie, o pesquisador encontrou um objeto serializado com pickle contendo o client_id e o client_secret OAuth do Google em texto simples. Descobriu que o client secret também servia como SECRET_KEY do Flask, o que significa que o mesmo valor guardava e verificava a assinatura. Como a chave de assinatura estava exposta dentro do próprio cookie, o pesquisador conseguia recalcular assinaturas válidas offline e forjar dados de sessão arbitrários.
O endpoint de callback lê os dados do fluxo OAuth da sessão e os passa para pickle.loads. Com uma sessão forjada, um atacante poderia fornecer uma carga pickle maliciosa, tornando isso um caminho de execução remota de código sem autenticação. O pesquisador verificou o problema de forma segura usando uma carga que apenas acionava time.sleep, evitando executar comandos nos sistemas de produção do Google.
A descoberta ilustra como armazenar segredos em dados de sessão do lado do cliente e desserializar dados pickle não confiáveis podem se somar e resultar em uma vulnerabilidade crítica. A falha rendeu uma recompensa de US$ 90 mil.
🇷🇺 Русский
Как я нашёл уязвимость удалённого выполнения кода в Google на 90 000 долларов
Исследователь безопасности обнаружил уязвимость удалённого выполнения кода на сайтах документации для разработчиков Google. Изучая поток OAuth, общий для этих сайтов, исследователь заметил, что эндпоинт /oauth2authorize устанавливает необычно большой cookie сессии Flask, около 1 200 байт, что намного больше, чем нужно для CSRF-токена и URL возврата. Cookie сессий Flask подписываются, но не шифруются, поэтому их содержимое могло прочитать любой, кто владел таким cookie.
Декодирование cookie показало объект, сериализованный через pickle, в котором открытым текстом находились client_id и client_secret OAuth от Google. Исследователь выяснил, что client secret также использовался как SECRET_KEY для Flask, то есть одно и то же значение и создавало, и проверяло подпись. Поскольку ключ подписи был раскрыт в самом cookie, исследователь мог офлайн пересчитывать корректные подписи и подделывать произвольные данные сессии.
Эндпоинт обратного вызова читает данные потока OAuth из сессии и передаёт их в pickle.loads. С подделанной сессией злоумышленник мог подставить вредоносную полезную нагрузку pickle, что превращало это в путь удалённого выполнения кода без аутентификации. Исследователь безопасно проверил проблему, используя полезную нагрузку, которая лишь вызывала time.sleep, не выполняя никаких команд на производственных системах Google.
Отчёт наглядно показывает, как хранение секретов в клиентских данных сессии и десериализация недоверенных данных pickle могут сочетаться в критическую уязвимость. За эту ошибку была выплачена награда в размере $90 000.
🇨🇳 简体中文
我如何在谷歌发现一个价值90,000美元的远程代码执行漏洞
一位安全研究人员在谷歌的开发者文档站点中发现了一个远程代码执行漏洞。在梳理这些站点共享的OAuth流程时,研究人员注意到 /oauth2authorize 端点设置了一个异常大的Flask会话Cookie,约为1,200字节,远超CSRF令牌和返回URL所需的大小。Flask会话Cookie经过签名但未加密,因此任何持有该Cookie的人都可以读取其内容。
解码该Cookie后,研究人员发现其中有一个经过pickle序列化的对象,以明文形式包含谷歌的OAuth client_id和client_secret。研究人员还发现,该client secret同时也被用作Flask的SECRET_KEY,意味着同一个值既用于持有又用于验证签名。由于签名密钥暴露在Cookie本身之中,研究人员能够离线重新计算有效签名,并伪造任意会话数据。
回调端点从会话中读取OAuth流程数据并将其传递给pickle.loads。借助伪造的会话,攻击者可以提供恶意的pickle载荷,从而形成一条无需身份验证的远程代码执行路径。研究人员使用仅触发time.sleep的载荷安全地验证了该问题,避免了在谷歌的生产系统上执行任何命令。
此次发现表明,将机密信息存储在客户端会话数据中,以及对不可信的pickle数据进行反序列化,可能相互叠加,形成严重漏洞。该漏洞获得了90,000美元的赏金。