Vercel breach 2026: anatomia di un attacco supply chain via OAuth

Il breach di Vercel di aprile 2026 è un attacco supply chain in cui la compromissione di un tool AI di terze parti (Context.ai) ha fornito all'attaccante un OAuth token valido per accedere al Google Workspace di un dipendente Vercel, consentendo poi l'accesso ad ambienti interni e variabili d'ambiente non marcate come sensitive.

Non è stato violato il perimetro di Vercel direttamente. Non c'è stata una CVE sfruttata nelle loro API, nessun RCE, nessun bruteforce. Il punto d'ingresso era un'estensione Chrome installata da un dipendente, firmata con OAuth, con permessi ampi. È questo il meccanismo che va capito.

Indice


Timeline degli eventi

Data Evento
Febbraio 2026 un dipendente di Context.ai viene infettato da Lumma Stealer. Credenziali Google Workspace, Supabase, Datadog e Authkit vengono esfiltrate.
Marzo 2026 Context.ai identifica e blocca un accesso non autorizzato al proprio AWS. Il Chrome extension di Context.ai viene silenziosamente rimosso dal Chrome Web Store da Google il 27 marzo.
Aprile 2026 (seconda settimana) l'attaccante usa OAuth token compromessi di Context.ai per accedere al Google Workspace dell'account Vercel colpito.
19 aprile 2026 Vercel pubblica il primo security bulletin, incluso l'IOC dell'app OAuth.
20 aprile 2026 Vercel conferma che i pacchetti npm non sono stati compromessi. ShinyHunters reclama la responsabilità e mette in vendita i dati per 2 milioni di dollari.
21 aprile 2026 indagini in corso con Mandiant, GitHub, Microsoft, npm e Socket.

La catena di attacco

Tutto parte da un dipendente di Context.ai che scarica uno script malevolo distribuito come exploit per Roblox. Il file installa Lumma Stealer, che raccoglie silenziosamente credenziali dal browser, token OAuth e file di configurazione dalla macchina infetta. Tra i dati esfiltrati c'è l'account [email protected], con accesso privilegiato ai sistemi interni dell'azienda.

Con quelle credenziali, l'attaccante entra nell'ambiente AWS di Context.ai a marzo 2026. Lì trova il database dei token OAuth raccolti dall'estensione Chrome: ogni utente che aveva installato il tool e fatto login con Google aveva lasciato un refresh token valido nei loro sistemi. Uno di questi token appartiene a un dipendente Vercel che aveva usato il proprio account enterprise per registrarsi.

Il refresh token è sufficiente per ottenere un nuovo access token Google senza conoscere la password e senza toccare MFA. L'attaccante accede al Google Workspace di Vercel, identifica gli ambienti interni associati all'account e legge le variabili d'ambiente non marcate come sensitive. A quel punto ha in mano API key, token di database e signing key di un subset di clienti Vercel.


Context.ai: dove è iniziato tutto

Context.ai è un tool AI che si installa come estensione Chrome e si connette all'account Google dell'utente tramite OAuth. L'estensione (Chrome Extension ID: omddlmnhcofjbnbflmjginpjjblphbgk) aveva due OAuth grant attivi: uno per accedere al Google Workspace dell'utente (Gmail, Calendar, Docs) e uno incorporato nell'estensione stessa per la lettura dei file Google Drive, tramite l'app 110671459871-f3cq3okebd3jcg1lllmroqejdbka8cqq.apps.googleusercontent.com.

Jaime Blasco (CTO di Nudge Security) ha identificato che Google ha rimosso l'estensione dal Chrome Web Store il 27 marzo 2026, ben prima che il breach Vercel diventasse pubblico.

Context.ai ha confermato nel proprio security bulletin che l'attaccante ha utilizzato un OAuth token compromesso per accedere al Google Workspace di Vercel. Vercel non è un cliente diretto di Context.ai, ma almeno un dipendente Vercel aveva installato l'estensione usando il proprio account enterprise e aveva concesso permessi "Allow All". La configurazione OAuth interna di Vercel consentiva a quel grant di propagarsi all'interno del loro Google Workspace enterprise, rendendo un singolo dipendente il punto d'ingresso per l'intera organizzazione.


Il ruolo di Lumma Stealer

Lumma Stealer è un malware-as-a-service (MaaS) di tipo infostealer, venduto su forum underground dal 2022. Raccoglie credenziali salvate nel browser, cookie di sessione attivi, token OAuth e refresh token, wallet crypto e file con pattern specifici come .env, config.json e id_rsa. La distribuzione attraverso script di gioco malevoli è una tecnica documentata: gli script vengono pubblicati come "auto-farm" o "executor" su Discord, GitHub e siti di gaming, e gli utenti li eseguono perché credono di installare uno cheat.

Nel caso specifico, Hudson Rock ha rilevato che la macchina compromessa del dipendente Context.ai conteneva credenziali Google Workspace aziendali, token Supabase e Datadog, credenziali Authkit, e l'account [email protected], che è stato probabilmente il vettore di escalation verso l'AWS di Context.ai, dove risiedevano i token OAuth dei loro utenti.


Come funziona l'escalation via OAuth

Quando il dipendente Vercel installa l'estensione Context.ai e clicca "Sign in with Google", Google mostra una consent screen con i permission scope richiesti. L'utente accetta, Google emette un access_token e un refresh_token, e Context.ai li salva nei propri sistemi AWS. Da quel momento in poi, Context.ai usa quei token per leggere mail e Drive dell'utente ogni volta che serve.

Fin qui è il funzionamento normale di OAuth. Il problema è cosa succede quando quei token finiscono nelle mani sbagliate.

L'attaccante, una volta dentro l'AWS di Context.ai, recupera il database dei token OAuth. Con il refresh_token del dipendente Vercel, chiama il Google Token Endpoint e ottiene un nuovo access_token valido, senza conoscere la password e senza alcun prompt MFA. A quel punto accede al Google Workspace Vercel come se fosse l'utente legittimo, identifica gli ambienti interni associati all'account e legge le variabili d'ambiente non marcate come sensitive.

Il refresh token è permanente finché non viene revocato esplicitamente. Disinstallare l'estensione non revoca il grant: finché l'utente non rimuove l'accesso da myaccount.google.com/permissions, il token rimane valido e sfruttabile.

Perché i permessi "Allow All" sono pericolosi

Quando un'app OAuth chiede lo scope https://www.googleapis.com/auth/gmail.readonly, Google mostra chiaramente "Read your email messages." Quando invece usa scope aggregati come https://www.googleapis.com/auth/cloud-platform o combinazioni ampie, l'interfaccia di consenso può essere meno esplicita su cosa si sta concedendo.

La policy di Google Workspace delle aziende può limitare quali app OAuth di terze parti possono essere autorizzate dai dipendenti. Se quella policy era assente o permissiva in Vercel, un singolo dipendente ha potuto concedere un accesso che normalmente richiede approvazione del Google Workspace Admin.


Cos'è stato compromesso in Vercel

Confermato

Le variabili d'ambiente non marcate come "sensitive" di un subset limitato di clienti (API key, token di database, signing key, webhook secret) sono state esposte. Vercel ha contattato direttamente i clienti coinvolti. Risulta compromesso anche un accesso ad ambienti interni Vercel, la cui natura esatta non è stata divulgata.

Confermato non compromesso

Le environment variables marcate come "sensitive" sono memorizzate in modo da non poter essere lette, nemmeno dagli ingegneri Vercel, e non ci sono evidenze di accesso. I pacchetti npm di Vercel, inclusi Next.js e Turbopack, sono stati verificati integri in collaborazione con GitHub, Microsoft, npm e Socket.

In investigazione

Lo scope completo dei dati esfiltrati, il numero esatto di clienti coinvolti e quali sistemi interni siano stati raggiunti sono ancora oggetto di indagine. Vercel ha descritto il threat actor come "highly sophisticated" sulla base della velocità operativa e della conoscenza dettagliata dei loro sistemi.

Nota sulla rivendicazione ShinyHunters: il gruppo ha dichiarato di aver rubato i dati e li sta vendendo per 2 milioni di dollari. Austin Larsen di Google Threat Intelligence Group (GTIG) ha però precisato che si tratta probabilmente di un impostore che usa il nome ShinyHunters per aumentare la propria notorietà.


Indicatori di compromissione (IOC)

App OAuth da verificare immediatamente

Vercel ha pubblicato due IOC relativi alle app OAuth di Context.ai. Gli amministratori Google Workspace devono verificare se queste app sono autorizzate nel proprio tenant.

App OAuth principale Context.ai:

110671459871-30f1spbu0hptbs60cb4vsmv79i7bbvqj.apps.googleusercontent.com

App OAuth incorporata nell'estensione Chrome (Google Drive read access):

110671459871-f3cq3okebd3jcg1lllmroqejdbka8cqq.apps.googleusercontent.com

Chrome Extension rimossa dal Web Store:

Extension ID: omddlmnhcofjbnbflmjginpjjblphbgk

Come verificare nel proprio Google Workspace

Da Admin Console: Security > API controls > App access control, cercando le Client ID elencate sopra.

Via Google Admin SDK è possibile automatizzare l'audit degli eventi di autorizzazione OAuth:

from googleapiclient.discovery import build
from google.oauth2 import service_account

# richiede Service Account con dominio-wide delegation
SCOPES = ['https://www.googleapis.com/auth/admin.reports.audit.readonly']

def check_oauth_app_usage(credentials_file, target_client_id, domain):
    creds = service_account.Credentials.from_service_account_file(
        credentials_file, scopes=SCOPES
    )
    service = build('admin', 'reports_v1', credentials=creds)

    results = service.activities().list(
        userKey='all',
        applicationName='token',
        eventName='authorize',
        filters=f'client_id=={target_client_id}'
    ).execute()

    activities = results.get('items', [])
    if activities:
        print(f"[!] App {target_client_id} autorizzata da:")
        for activity in activities:
            actor = activity.get('actor', {}).get('email', 'unknown')
            time = activity.get('id', {}).get('time', 'unknown')
            print(f"    - {actor} at {time}")
    else:
        print(f"[+] Nessuna autorizzazione trovata per {target_client_id}")

IOC_MAIN = "110671459871-30f1spbu0hptbs60cb4vsmv79i7bbvqj"
IOC_DRIVE = "110671459871-f3cq3okebd3jcg1lllmroqejdbka8cqq"

check_oauth_app_usage("service-account.json", IOC_MAIN, "yourdomain.com")
check_oauth_app_usage("service-account.json", IOC_DRIVE, "yourdomain.com")

Per un singolo account Google personale è sufficiente andare su myaccount.google.com/permissions e verificare tutte le app con scope ampi, in particolare quelle con accesso a Gmail o Drive.


Raccomandazioni operative

Per chi usa Vercel

Tutte le variabili d'ambiente non marcate come "sensitive" vanno trattate come compromesse e ruotate immediatamente: API key di servizi terzi, token di database, JWT secret, webhook secret. Cancellare il progetto o l'account Vercel non è sufficiente, perché le credenziali esfiltrate restano valide sui sistemi di destinazione.

# verifica quali env vars non sono sensitive via Vercel CLI
vercel env ls --environment production

Dopo la rotation, marca tutto come sensitive dalla dashboard (Settings > Environment Variables > edit > abilita "Sensitive") o via CLI:

vercel env add MY_SECRET_KEY production
# il CLI chiede se marcarla come sensitive

Controlla il log di attività per il periodo 15-21 aprile 2026 (dashboard > Team Settings > Activity Log) e verifica che non ci siano deployment strani. Assicurati che Deployment Protection sia impostato almeno su "Standard" e ruota i relativi token se configurati.

Per Google Workspace admins

La misura strutturale è limitare quali app OAuth di terze parti i dipendenti possono autorizzare autonomamente. Da Admin Console: Security > API controls > App access control, impostare "Restrict access to Google services" su "Trusted apps only" e costruire una lista di app approvate.

Oltre ai due IOC pubblicati da Vercel, conviene fare un audit delle app OAuth esistenti nel workspace cercando quelle con scope su mail o drive non giustificati dal loro use case, con publisher non verificato da Google, o installate da un numero molto ridotto di account (spesso un solo dipendente).

Per tutti i developer

Usa chiavi diverse per ambiente di sviluppo e produzione. Se una dev key viene esfiltrata, la produzione rimane intatta. Sul proprio account personale Google o GitHub, revoca periodicamente le app OAuth che non usi più, soprattutto le estensioni browser: mantengono l'accesso finché non vengono esplicitamente rimosse dal pannello permissioni, anche dopo la disinstallazione.


Il pattern più ampio: OAuth come vettore laterale

Questo breach non è isolato. Jaime Blasco di Nudge Security ha documentato una serie di attacchi con la stessa struttura nell'ultimo anno: Salesloft Drift, Gainsight, e ora Context.ai/Vercel. Cambiano i nomi dei vendor, la dinamica resta identica.

I tool AI e SaaS di nuova generazione richiedono OAuth grant ampi per funzionare (leggono mail, Drive, calendar), centralizzano questi token nei propri sistemi cloud, e spesso sono startup giovani senza programmi di sicurezza maturi. Il risultato è che diventano un hub di accesso a decine o centinaia di organizzazioni enterprise. Dal punto di vista dell'attaccante, compromettere un vendor del genere è molto più efficiente che attaccare ogni target singolarmente: è la stessa logica che ha reso redditizi gli attacchi alla supply chain software (SolarWinds, 3CX, XZ Utils), applicata al layer identità.

Quello che rende OAuth particolarmente insidioso come vettore è che i refresh token non scadono se non revocati esplicitamente, l'accesso tramite OAuth bypassa MFA senza richiedere la password dell'utente, e i log mostrano accessi legittimi perché il consenso è stato concesso volontariamente. Non c'è nulla di anomalo da rilevare fino a quando non è troppo tardi.

Come ha scritto Blasco: "OAuth è il nuovo lateral movement. Finché l'industria non tratta i token OAuth come credenziali ad alto valore, continueremo a leggere lo stesso breach writeup con i nomi dei vendor cambiati."


Riferimenti

  1. Vercel security bulletin - April 2026
  2. The Hacker News - Vercel breach analysis
  3. Google - revoca accessi app OAuth
  4. Vercel docs - sensitive environment variables
  5. Vercel docs - activity log

Aggiornato al 21 aprile 2026. La situazione è ancora in evoluzione: Vercel continua a indagare con Mandiant l'entità completa dell'esfiltrazione.