Уязвимост в начина, по който разработчиците внедряват API на Google за Gemini Live, позволява на нападатели да компрометират базирани на браузър сесии за гласов изкуствен интелект (AI), да пренаписват системните подкани (prompts) и да задействат неоторизирано изпълнение на код. Всичко това се дължи на неправилна конфигурация на токените, която води началото си от собствената примерна реализация (reference implementation) на Google.

Репортерът по сигурността Алвин Фердиансях отбелязва, че API за Gemini Live поддържа гласови асистенти в реално време чрез постоянни WebSocket връзки. Съществуват две крайни точки (endpoints): BidiGenerateContent, която използва суров API ключ и е предназначена за комуникация между сървъри, и BidiGenerateContentConstrained, проектирана за браузърни клиенти, използващи краткотрайни временни токени (ephemeral tokens), така че API ключът никога да не достига до клиента.

Всяка сесия започва с изпратена от клиента рамка за настройка (setup frame), която дефинира модела, системните инструкции и наличните инструменти, включително изпълнение на код, Google Search и извличане на URL адреси. Критичното тук е, че всяко поле в тази рамка е незадължително (optional), което означава, че всичко, което не е изрично заключено от бекенда, остава под контрола на клиента.

Временните токени се генерират чрез бекенд повикване, което може да включва полето live_connect_constraints, по-конкретно bidi_generate_content_setup, за да се заключат моделът, системната подкана и инструментите.

Без него собствената документация на Google потвърждава, че сървърът приема всичко, което клиентът изпрати в своята setup рамка. Удостоверяването и упълномощаването стават напълно разделени: валидният токен доказва, че клиентът има право да се свърже, но не и какво има право да прави.

В допълнение към това, официалното примерно хранилище на Google (google-gemini/gemini-live-api-examples) доставя server.py, който генерира токени, използвайки само uses, expire_time и new_session_expire_time, като напълно изпуска live_connect_constraints. Екипите, които изграждат своите решения въз основа на този пример, наследяват уязвимостта по подразбиране.

По време на тестване на потребителски гласов асистент, Алвин Фердиансях прехваща отговора за генериране на токен чрез Burp Suite и установява липсата на полето bidi_generate_content_setup, което потвърждава, че сесията е неограничена, въпреки името на крайната точка "Constrained". Самата регистрация изисквала само имейл и OTP код, което отнело по-малко от две минути за получаване на валиден токен.

Свързвайки се директно с WebSocket, изследователят изпраща персонализирана рамка за настройка, пренаписваща системната инструкция и активираща изпълнението на код (codeExecution). Сървърът отговорил със setupComplete, потвърждавайки приемането. Последващ Python скрипт се изпълнил успешно в пясъчника gVisor на Google.

За да изключи вероятността от халюциниран изходен резултат, изследователят използва доказателство, базирано на nonce: изчисляване на SHA-256 хешове, обвързани с произволна стойност и версията на ядрото на средата за изпълнение на пясъчника, които не могат да бъдат предварително изчислени без реално изпълнение. Хешовете съвпаднали, потвърждавайки реалното изпълнение на код.

Пясъчникът gVisor предотвратява изходящия мрежов достъп и избягването от хоста (host escape), ограничавайки щетите до злоупотреба с ресурси в изолираната среда и проучване (reconnaissance), а не до странично движение в мрежата. Все пак неограниченият достъп позволява на всеки регистриран потребител да консумира платени API ресурси неограничено време чрез подновяване на токени.

Корекцията изисква едно единствено добавяне към повикването за генериране на токени: попълване на live_connect_constraints.bidi_generate_content_setup с желания модел, системна подкана и празен масив за инструменти. Това заключва всички параметри на сесията от страна на сървъра, затваряйки напълно пътя за инжектиране.

Всеки продукт, който използва временни токени за ориентирани към браузъра интеграции с Gemini Live без това поле, е вероятно да бъде изложен на същия клас уязвимост.