Konferencja Mega Sekurak Hacking Party w Krakowie – 26-27 października!
Podatności w Google Looker Studio umożliwiały eksfiltrację danych m.in. z BigQuery
Badacze bezpieczeństwa z Tenable odkryli podatności w Google Looker Studio. Luki mogły umożliwić atakującym nieautoryzowane pobranie lub modyfikację danych w usługach Google, takich jak BigQuery czy Google Sheets. Firma po zgłoszeniu załatała wszystkie zidentyfikowane problemy.
TLDR:
- Badacze z Tenable odkryli podatności w Google Looker Studio umożliwiających dostęp do danych z usług Google (m.in. BigQuery, Google Sheets).
- Luki miały charakter cross-tenant – pozwalały na dostęp do danych między różnymi organizacjami.
- Ataki obejmowały scenariusze zero-click (bez interakcji ofiary) oraz one-click (wymagające kliknięcia w link).
- Kluczowe problemy dotyczyły m.in. SQL injection, błędów w obsłudze aliasów oraz kopiowania poświadczeń źródeł danych.
- Atakujący mogli potencjalnie wykonywać dowolne zapytania SQL w zakresie uprawnień ofiary i eksfiltrować dane.
- Google załatało wszystkie podatności – użytkownicy nie muszą podejmować dodatkowych działań.
Dostęp do danych był możliwy między różnymi firmami/organizacjami korzystającymi z chmury Google (cross-tenant). Odkryte podatności umożliwiały atakującym uruchamianie dowolnych zapytań SQL w bazach danych ofiar oraz eksfiltrację wrażliwych danych przy użyciu ataków zarówno w mechanizmie one-click, jak i zero-click.
Potencjalnie dotyczyło to wszystkich organizacji korzystających z połączeń – connectorów (takich jak Google Sheets, BigQuery, Spanner, PostgreSQL, MySQL, Cloud Storage) – w ramach Looker Studio. Wszystkie problemy zostały usunięte przez Google po zgłoszeniach badaczy z Tenable.
Looker Studio to platforma do business intelligence i wizualizacji danych, która pozwala użytkownikom tworzyć interaktywne raporty. Łącząc się z różnymi źródłami, takimi jak Google Analytics, BigQuery lub bazy SQL, umożliwia generowanie automatycznie aktualizowanych zestawień. Ponieważ działa w infrastrukturze Google Cloud, w dużym stopniu opiera się na modelu współdzielenia uprawnień podobnym do Google Docs, gdzie do zasobów mają dostęp konkretni użytkownicy lub każda osoba posiadająca publiczny link.

Aby zrozumieć, dlaczego te podatności są tak krytyczne, najpierw musimy przyjrzeć się temu, jak Looker Studio obsługuje dostępy. Gdy do tworzonego raportu podłączamy bazę danych, musimy zdecydować, która “tożsamość” ma być wykorzystywana do tego połączenia. Looker Studio oferuje dwie możliwości:
- Dane uwierzytelniające oglądającego
W tym przypadku raport do pobierania danych używa uprawnień użytkownika, który właśnie go ogląda.
Jest to teoretycznie najbezpieczniejszy sposób, ponieważ zapewnia, że użytkownicy widzą tylko to, co mają prawo zobaczyć. Jeśli użytkownik nie ma dostępu do źródłowej bazy danych, nie obejrzy wygenerowanego na jej podstawie raportu.
W takim scenariuszu każdy użytkownik ma własny, indywidualny token uwierzytelniający.
- Dane uwierzytelniające właściciela
W takim przypadku raport wykorzystuje uprawnienia właściciela, niezależnie od tego, kto go ogląda. Pozwala to udzielić dostępu do raportu osobom, które nie mają uprawnień do korzystania ze źródła danych, na przykład udostępnić raport sprzedaży klientowi, który nie ma dostępu do twojej bazy sprzedażowej.
Dane są więc pobierane przy użyciu tokenu uwierzytelniającego właściciela.
Badacze szukali ścieżek ataku na oba sposoby uwierzytelniania. Najpierw badali, czy można zmanipulować raport tak, aby zmusić użytkownika do nieświadomego wykonania zapytań lub manipulacji danymi, do których ma uprawnienia. Sprawdzali też, czy możliwe jest wysłanie danych “na zewnątrz”. Ponieważ wymaga to kliknięcia przez ofiarę konkretnego linku, ataki te sklasyfikowali jako one-click. Wykorzystują bowiem uprawnienia dostępu samej ofiary.
Sprawdzano też ataki na raporty korzystające z poświadczeń właścicieli. Badacze wiedzieli, że wysłanie spreparowanego żądania do publicznego lub współdzielonego raportu powoduje, że usługa Looker Studio obsłuży je wykorzystując dane właściciela zasobu. Ponieważ dzieje się to całkowicie po stronie serwera, bez potrzeby kliknięcia czegokolwiek przez ofiarę, badacze sklasyfikowali ten atak jako zero-click.
Looker Studio działa jako warstwa wizualizacji dla wielu danych w organizacjach. Aby funkcjonować, używa połączeń (connectors), które integrują bazowe źródła danych (np. BigQuery lub Cloud SQL) z raportem. Ważną zaletą Looker Studio (a jednocześnie problemem pod kątem bezpieczeństwa), jest opcja live data.
W przeciwieństwie do statycznych zestawień, raporty Looker Studio działają dynamicznie. Gdy dane zostaną zaktualizowane, tworzone w ramach raportu wykresy aktualizują się po odświeżeniu strony przez użytkownika.
W tym celu Looker Studio działa jako pośrednik między bazą danych a użytkownikiem. Przy otwarciu raportu, przeglądarka wysyła żądanie do Looker Studio, które następnie jest “tłumaczone” na zapytanie SQL i wysyłane do źródłowej bazy danych.
Złośliwe aliasy
Badacze uruchomili Proof of Concept korzystając z BigQuery, ale podatność dotyczyła również innych źródeł danych. Zaczęli od sprawdzenia ruchu sieciowego wykonywanego podczas wczytywania raportu. Kluczowe okazało się żądanie o nazwie batchedDataV2.
Okazało się, że Looker Studio generuje unikalne aliasy dla każdej kolumny, które jako JSON są przekazywane w ciele żądania. Backend pobierał te dane (de facto kontrolowane przez użytkownika) i… wstawiał je bezpośrednio do zapytania SQL, co oznaczało w tym przypadku możliwość nadania własnych aliasów w żądaniu kolumn z BigQuery:
| SELECT column AS [USER_CONTROLLED_ALIAS] FROM table… |
Listing 1 – uproszczone zapytanie z parametrami kontrolowanymi przez użytkownika
Stali czytelnicy mogą już podejrzewać, co działo się dalej. Badacze chcieli wykorzystać takie działanie backendu, aby wstrzykując odpowiednie parametry do zapytania uzyskać dostęp do innych danych w bazie. Standardowo bowiem zwracane są tylko informacje w zakresie zdefiniowanym przy tworzeniu raportu.
Firma Google przygotowała jednak zabezpieczenia przed takimi próbami. Użycie kropki w żądaniu (tabele w BigQuery zawierają je w swoich nazwach – np. project.dataset.table) powodowało jej zamianę na znak “_”. Z kolei spacja była po prostu usuwana.
Badacze skorzystali więc z kilku właściwości, które pozwoliły im na obejście zabezpieczeń. Filtry Google usuwały spacje, ale ignorowały komentarze – a te są traktowane przez silnik SQL jak spacje (a ściślej: whitespace). Można więc stworzyć całkowicie poprawne zapytanie oddzielając części zapytania ciągiem /**/ (pustym komentarzem).
| SELECT * FROM table…SELECT/**/*/**/FROM/**/table… |
Listing 2 – dwa przykładowe zapytania, które zadziałają tak samo
Z kolei filtrowanie kropek ominięto korzystając z funkcji CHR() oraz CONCAT(), dzięki którym znak był wstawiany w zapytaniu już po sprawdzeniu jego treści:
| SELECT * FROM project.dataset.table…EXECUTE IMMEDIATE CONCAT( ‘SELECT * FROM project’, CHR(46), /* 46 to kod ASCII dla kropki */ ‘dataset’, CHR(46), ‘table…’); |
Listing 3 – kolejne dwa przykładowe zapytania, które w BigQuery zadziałają tak samo

Efekt? Możliwość wykonania dowolnego zapytania SQL w obrębie całego projektu na Google Cloud Platform – dzięki uprawnieniom właściciela raportu. Podatność ta mogła zostać wykorzystana, jeśli atakujący posiadał publiczny link lub raport został mu udostępniony.
Kopiowanie poświadczeń
Drugim odkryciem badaczy był problematyczny sposób obsługi funkcji kopiowania raportu w Looker Studio.

Sprawdzili, jak zakończy się próba skopiowania raportu z poziomu użytkownika, który nie ma dostępu do edycji danych (może jedynie wyświetlać). Raport korzystał bowiem z uprawnień właściciela do źródła danych, więc badacze przetestowali, jak zostanie to obsłużone w kopii.
Okazało się, że przy kopiowaniu raportu faktycznie tworzone jest nowe źródło danych, ale… zachowuje ono poświadczenia oryginalnej bazy. Użytkownik jest jednak właścicielem stworzonego w ten sposób raportu, a więc może zarządzać tym źródłem. Ma również możliwość wykonywania własnych operacji w bazie danych.

Badacze uruchomili zapytanie tworzące nową tabelę:

Mimo że na tym etapie atakujący nie posiadałby danych uwierzytelniających dla oryginalnej bazy danych, backend korzystał z poświadczeń raportu ofiary. Oczom badaczy ukazał się jednak komunikat błędu:

Ale nie przeszkodziło to w niczym – tabela i tak została utworzona w oryginalnej bazie (czyli: u ofiary, która udostępniła podgląd raportu atakującym lub wszystkim użytkownikom mającym link).

Efekt jest podobny do tego przy złośliwych aliasach – atakujący uzyskuje dostęp i możliwość operacji na danych w zakresie uprawnień ofiary tworzącej raport.
Cross-tenant SQL injection w BigQuery poprzez native functions
Gdy badacze znaleźli już podatności działające jako one-click, stało się jasne: jeśli możemy zmusić przeglądarkę ofiary do wykonania naszego kodu pod jej własną tożsamością, model bezpieczeństwa platformy będzie działał dla nas, a nie przeciwko nam.
Ukryte przygotowanie ataku: manipulowanie połączeniem
Standardowo interfejs Looker Studio pozwala łączyć raporty tylko ze źródłami danych, do których mamy uprawnienia. Jednak tworzenie tych połączeń odbywa się przez żądania, które wykonuje przeglądarka użytkownika.
Badacze zmodyfikowali je tak, aby zastąpić oznaczenie własnego projektu projektem “ofiary” (w tym przypadku: innego projektu testowego, do którego testowane konto nie miało dostępu).

Z racji braku poprawnej autoryzacji na tym etapie nie było możliwe pobrania faktycznych danych z podłączonego w ten sposób źródła, jednak konfiguracja raportu wskazywała na tabelę należącą do “ofiary”. Jako dane uwierzytelniające były jednak wykorzystywane poświadczenia użytkownika wyświetlającego w danym momencie raport.

Celem było wykonanie operacji w bazie danych przy wyświetleniu raportu przez “ofiarę”, która choć nie miała kontroli nad raportem – miała uprawnienia dostępu do bazy, która była do niego podłączona. Aby to osiągnąć, badacze skorzystali z modułu Native Functions.
Dimension w Looker Studio to kategoria lub konkretne pole w źródłowych danych. Twórca (lub użytkownik z uprawnieniami do edycji) raportu może wykonywać podstawowe obliczenia na tych polach, aby raport prezentował informacje w pożądanej formie. Bardziej złożone obliczenia/operacje można wykonać dzięki NATIVE_DIMENSION.
Funkcja ta pozwala wykonywać polecenia SQL bezpośrednio w Looker Studio, a backend uruchamia je w bazie danych, aby w raporcie zwrócić ich wynik. Dzieje się to podczas wyświetlania raportu. Można było więc – modyfikując żądania – dodać źródło danych należące do “ofiary”, dodać dimension z złośliwym zapytaniem SQL i udostępnić raport ofierze.

Ponieważ źródło danych jest ustawione na dane uwierzytelniające użytkownika wyświetlającego raport, ofiara de facto sama wykonuje złośliwe zapytanie SQL, nawet tego nie zauważając.
Google próbuje jednak blokować niebezpieczne polecenia SQL – wpisanie klasycznego SELECT * FROM table, Looker Studio zwróciłoby błąd. Weryfikacja ta działała jednak na podstawie słów kluczowych, więc znów z pomocą przyszły wspomniane wcześniej komentarze SQL wstawione między części poleceń. Przykładowo – zamiast SELECT użyto SEL/**/ECT. Filtr nie zablokował tak zbudowanych zapytań, jednak badacze nie chcieli poprzestawać na jednym zapytaniu.
BigQuery, podobnie jak wiele baz SQL, obsługuje wiele działań w ramach jednego zapytania. Można pisać kilka poleceń SQL oddzielonych średnikami i zamknąć je w bloku BEGIN…END. Pozwala to na wykonanie bardziej złożonych operacji bezpośrednio w SQL.
Badacze stworzyli więc cały “program”, który wykonywał zapytania do tabeli INFORMATION_SCHEMA.COLUMNS (opisującej strukturę bazy danych) aby znaleźć wszystkie nazwy tabel i kolumn, do których ofiara ma dostęp. Następnie w pętli odpytywano wszystkie tabele, ich kolumny oraz wiersze.
Pozostało jeszcze znaleźć sposób na wysłanie pozyskanych w ten sposób danych “na zewnątrz”. Złośliwe zapytania były wykonywane z poziomu użytkownika, więc badacze we własnym projekcie utworzyli serię pustych tabel i udostępnili je publicznie. Każda tabela była przypisana innej literze z alfabetu lub cyfrze. Gdy w ramach złośliwych zapytań uzyskiwali jakieś dane, wykonywali polecenia SELECT do własnej tabeli z odpowiednią literą. Mimo że zapytania te nic nie zwracały, były one zapisywane w logach ich projektu. W ten sposób byli w stanie przeglądając te wpisy ułożyć z nich sekwencję i odtworzyć dane ofiary.

Potencjalny atakujący mógłby więc stworzyć złośliwy raport i udostępnić go ofierze lub osadzić go na stronie internetowej. W momencie gdy ofiara go otwiera (lub odwiedza stronę, na której jest osadzony), jej przeglądarka:
- Łączy się ze źródłem danych, używając swoich danych uwierzytelniających (które wskazuje na BigQuery w jej organizacji).
- Wykonuje zapytania z NATIVE_DIMENSION.
- Złośliwy skrypt uruchamia się, wyodrębniając wszystkie nazwy tabel i kolumn BigQuery w projekcie ofiary, a następnie wszystkie dane z nich.
- Każdy pozyskany znak “ping” do jednej z publicznych tabel atakującego.
- Atakujący przegląda logi i odtwarza całą bazę danych ofiary.
Okazuje się, że nie zawsze dostęp “tylko do odczytu” oznacza to, czego się spodziewamy. Firma Google załatała wszystkie zgłoszone problemy globalnie. Nie są więc konieczne żadne manualne zmiany/aktualizacje po stronie klientów. Aby ograniczyć ryzyko tego typu ataków, dobrą praktyką jest minimalizacja uprawnień i dostępów – zarówno dla usług, jak i użytkowników w organizacji.
Instrukcja zarządzania dostępem przyznanym Looker Studio jest dostępna tutaj.Źródło: tenable.com
~Tymoteusz Jóźwiak
