{"id":1339,"date":"2026-06-16T20:26:09","date_gmt":"2026-06-16T20:26:09","guid":{"rendered":"https:\/\/thedigitalfortress.us\/?p=1339"},"modified":"2026-06-16T20:26:09","modified_gmt":"2026-06-16T20:26:09","slug":"google-vertex-ai-sdk-flaw-let-attackers-hijack-model-uploads-via-bucket-squatting","status":"publish","type":"post","link":"https:\/\/thedigitalfortress.us\/?p=1339","title":{"rendered":"Google Vertex AI SDK Flaw Let Attackers Hijack Model Uploads via Bucket Squatting"},"content":{"rendered":"<div>\n<p><span class=\"p-author\"><i class=\"icon-font icon-user\">\ue804<\/i><span class=\"author\">Swati Khandelwal<\/span><i class=\"icon-font icon-calendar\">\ue802<\/i><span class=\"author\">Jun 16, 2026<\/span><\/span><span class=\"p-tags\">Machine Learning \/ Cloud Security<\/span><\/p>\n<\/div>\n<div id=\"articlebody\">\n<div class=\"separator\" style=\"clear: both;\"><a href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgpiAGZTnvo43enaVYkna4ZSp217mwwW5kW8kZOhaSiLAxicjvHQY-3d8rdLN47bsRvxUIj6R0h_Ttr8NcIJrgz6k_mbcx94KLuPD29KdhFcYQsrV8htgg_iDYMV9aXbr21kv6BdYTzLNOOqQLpsCfpDC4XxDPnu77uVQ3oCYbIUfIpUKdmqx-rZZWj6P0\/s1700-e365\/Google-Vertex-AI.jpg\" style=\"display: block;  text-align: center; clear: left; float: left;\"><\/a><\/div>\n<p>A flaw in the Google Cloud Vertex AI SDK for Python let an attacker with no access to a victim&#8217;s project hijack the victim&#8217;s machine learning model upload and run code inside Google&#8217;s serving infrastructure.<\/p>\n<p>Palo Alto Networks Unit 42, which found and <a href=\"https:\/\/unit42.paloaltonetworks.com\/hijacking-vertex-ai-model\/\" target=\"_blank\">reported<\/a> the bug through Google&#8217;s bug bounty program, calls the technique \u00ab<b>Pickle in the Middle<\/b>\u00bb and said it saw no exploitation in the wild. Google has patched it; if you use the SDK, update to version 1.148.0 or later.<\/p>\n<p>The attacker needed only a Google Cloud project of their own and the victim&#8217;s project ID, which is often public. No credentials, no phishing, no foothold in the target.<\/p>\n<p>The flaw was in how the SDK chose a temporary Cloud Storage bucket for model uploads. If a user did not set a bucket, the SDK generated a predictable name from the project ID and region, such as\u00a0<i>project-vertex-staging-region<\/i>. It checked whether that bucket existed, but not whether the victim owned it.<\/p>\n<p>Because bucket names are globally unique, an attacker could create the expected bucket first in their own project. The victim&#8217;s SDK would then upload the model files to the attacker&#8217;s bucket. The attacker could then replace the uploaded model with a malicious one.<\/p>\n<div class=\"dog_two clear\">\n<div class=\"cf\"><a href=\"https:\/\/thehackernews.uk\/ai-cant-stop-d\" rel=\"nofollow noopener sponsored\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" class=\"lazyload\" alt=\"Cybersecurity\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEjPEV6-530TOlxG6PjrmdlY623wpBwduZ7t1HV6flcmO5R4q4AmfixDUzW0CrhlvMVNWbhvOIso-UDNTka4W_W9Chrdj_dglwBZwi7DuePM2IMIl-hfUYVIqBXgfpr_2619K8Gptb4LzwJ6gUbi7lWl2M8AFQJsHEaw63Q7tZ6708YGruiHrr0Y2W9YYxLQ\/s728-e100\/ThreatLocker-d.png\" width=\"729\" height=\"91\"\/><\/a><\/div>\n<\/div>\n<p>Many Python ML models are saved with\u00a0<a href=\"https:\/\/docs.python.org\/3\/library\/pickle.html\">pickle<\/a>\u00a0or\u00a0<a href=\"https:\/\/joblib.readthedocs.io\/en\/stable\/\">joblib<\/a>, which can run code when a file is loaded. When Vertex AI later loaded the swapped model, the attacker&#8217;s code executed inside the serving container.<\/p>\n<p><a name=\"more\"\/><\/p>\n<p>The attack depended on speed. Unit 42 measured about 2.5 seconds between the victim&#8217;s upload and Vertex AI reading the file. In its proof of concept, the attacker used a Cloud Function that triggered after upload and replaced the model in 1.4 seconds, before Vertex AI read it.<\/p>\n<p>The payload then stole an OAuth token from the serving container&#8217;s metadata server and sent it to the attacker. In Unit 42&#8217;s test environment, that token was not limited to the compromised deployment. It could access other model artifacts in the same Google-managed tenant project, including a full TensorFlow model with trained weights, as well as BigQuery metadata, access lists, tenant logs, GKE cluster names, and internal container image paths.<\/p>\n<div class=\"separator\" style=\"clear: both;\"><a href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEi44arRHIBKBINb19ia9izN1ZJEdRQb66daWeR8Q_rIie27guF-8nPTb_9ndCjSgscxjYfM3o4UjYP6rRfs2N4hV9jHjN69IGI0dqkkVtiUtJMtYfDtF48MORBQUcQeOWJCCbCmIDLfhqZWqIOavaonpG82K4yiGCYV2w11W_fqzdps5UUrFsrzZgQEXmA\/s1700-e365\/bucket.jpg\" style=\"clear: left; display: block; float: left;  text-align: center;\"><img decoding=\"async\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEi44arRHIBKBINb19ia9izN1ZJEdRQb66daWeR8Q_rIie27guF-8nPTb_9ndCjSgscxjYfM3o4UjYP6rRfs2N4hV9jHjN69IGI0dqkkVtiUtJMtYfDtF48MORBQUcQeOWJCCbCmIDLfhqZWqIOavaonpG82K4yiGCYV2w11W_fqzdps5UUrFsrzZgQEXmA\/s1700-e365\/bucket.jpg\" alt=\"\" border=\"0\" data-original-height=\"1110\" data-original-width=\"972\"\/><\/a><\/div>\n<p>The attack worked only under specific conditions: the victim&#8217;s default staging bucket did not already exist in that region, and the victim left the\u00a0<i>staging_bucket\u00a0<\/i>parameter unset. The first is common for a new project in Vertex AI in a region.<\/p>\n<p>The second depends on the developer relying on the SDK&#8217;s default rather than naming their own bucket.<\/p>\n<p>Unit 42 reported the flaw through Google&#8217;s Vulnerability Reward Program on March 5, 2026. It tested versions 1.139.0 and 1.140.0, the latest available at the time, and found both vulnerable.<\/p>\n<p>Google shipped an initial fix in\u00a0<a href=\"https:\/\/github.com\/googleapis\/python-aiplatform\/compare\/v1.143.0...v1.144.0\">v1.144.0<\/a>\u00a0on March 31, adding a random\u00a0uuid4\u00a0to the bucket name. It completed the fix in\u00a0<a href=\"https:\/\/github.com\/googleapis\/python-aiplatform\/releases\/tag\/v1.148.0\">v1.148.0<\/a>\u00a0on April 15, adding bucket ownership verification to block bucket squatting in\u00a0Model.upload(). As of publication, neither Unit 42 nor Google&#8217;s Vertex AI security bulletins list a CVE for the issue.<\/p>\n<div class=\"dog_two clear\">\n<div class=\"cf\"><a href=\"https:\/\/thehackernews.uk\/vpn-threat-report-m\" rel=\"nofollow noopener sponsored\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" class=\"lazyload\" alt=\"Cybersecurity\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhFlTC7RrRZGiFAgASS0noWSL0qsQGFVp8-Hvuw9yp3X3VKRuTcb5SsPX09wJzrdIM6pu1_5lS4EeZp7Sx4iYBpNJkrGnpr08yyaS1HQ5_5TxaCsP6O0OtHNuOkesn6CbNjao1GPulCJk-uljYMSfMZfBYNrngpe669t7jlRn1FqiEnXhsFD1WVkpaYIVgh\/s728-e100\/ai-d.jpg\" width=\"729\" height=\"91\"\/><\/a><\/div>\n<\/div>\n<p>Update to 1.148.0 or later so the ownership check is active. Also, set an explicit\u00a0staging_bucket\u00a0to a Cloud Storage location you control when uploading models. Because the flawed logic lives in the client SDK, check the\u00a0google-cloud-aiplatform\u00a0version wherever it runs, including notebooks, CI jobs, and training pipelines, not only production services.<\/p>\n<p>It is the second predictable-bucket-name flaw to surface in Vertex AI this year. Google patched\u00a0<a href=\"https:\/\/cloud.google.com\/vertex-ai\/docs\/security-bulletins\">CVE-2026-2473<\/a>\u00a0in February, a separate bucket-squatting bug in Vertex AI Experiments that also allowed cross-tenant code execution, model theft, and poisoning.<\/p>\n<p>Unit 42&#8217;s earlier work on\u00a0Vertex AI&#8217;s default service-agent permissions\u00a0traced a related path from a deployed AI agent into customer and tenant data.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>\ue804Swati Khandelwal\ue802Jun 16, 2026Machine Learning \/ Cloud Security A flaw in the Google Cloud Vertex AI SDK for Python let an attacker with no access to a victim&#8217;s project hijack&hellip;<\/p>\n","protected":false},"author":1,"featured_media":1340,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[622,2070,70,2,333,111,355,2071,795,984],"class_list":["post-1339","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-attackers","tag-bucket","tag-flaw","tag-google","tag-hijack","tag-model","tag-sdk","tag-squatting","tag-uploads","tag-vertex"],"_links":{"self":[{"href":"https:\/\/thedigitalfortress.us\/index.php?rest_route=\/wp\/v2\/posts\/1339","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/thedigitalfortress.us\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/thedigitalfortress.us\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/thedigitalfortress.us\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/thedigitalfortress.us\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1339"}],"version-history":[{"count":0,"href":"https:\/\/thedigitalfortress.us\/index.php?rest_route=\/wp\/v2\/posts\/1339\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/thedigitalfortress.us\/index.php?rest_route=\/wp\/v2\/media\/1340"}],"wp:attachment":[{"href":"https:\/\/thedigitalfortress.us\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1339"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/thedigitalfortress.us\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1339"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/thedigitalfortress.us\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1339"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}