Basi della sicurezza
La tua chiave API è trapelata. L'ordine in cui muoverti
Una chiave API è trapelata e non sai da cosa cominciare. Non tutte le chiavi nel frontend lo sono, e l'ordine conta più della velocità.

In breve
- Se una chiave API è trapelata, cosa fare per prima cosa dipende da quale chiave sia. Le chiavi pubblicabili stanno nel frontend e non chiedono nulla.
- Se è un segreto vero, stabilisci se la chiave può spendere soldi. È l'unica parte di questa storia su cui corre un orologio.
- Fermare una chiave e sostituire una chiave sono due comandi distinti presso ogni fornitore, e quasi tutti ti lasciano una finestra in cui funzionano entrambe.
- Poi leggi il log del fornitore per il periodo in cui la chiave è stata fuori, e lascia stare la cronologia Git finché la chiave non è morta.
Il messaggio arriva quasi sempre da un report di scansione, da GitHub che ti avvisa che in uno dei tuoi repository è spuntato un segreto, o da qualcuno che ha premuto F12 sul tuo sito e ti ha mandato uno screenshot. Comunque ti sia arrivato, adesso sai che una tua chiave API è trapelata e non sai da cosa cominciare.
Ecco la parte che guida dopo guida sbaglia: danno la stessa risposta per ogni chiave, e la risposta è sempre ruotarla. Alcune di quelle chiavi devono essere pubbliche e non chiedono nulla. Fra le altre, alcune stanno gonfiando una fattura mentre leggi questa riga, e altre hanno fatto tutto il danno il giorno del deploy. Sono tre situazioni diverse, e la prima mossa cambia in ognuna.
Prima di tutto: quella chiave è davvero un segreto?
Spesso no, e i numeri pendono abbastanza da poterlo dire chiaramente.
Abbiamo scansionato 31.056 applicazioni online e letto il JavaScript che ciascuna consegna al browser. Il controllo che cerca credenziali ha potuto rispondere su tutte, e 1.332 sono tornate con almeno una chiave che meritava una segnalazione. 1.142 di quelle erano chiavi API di Google, che è l'unico tipo del gruppo a trovarsi di solito esattamente dove deve stare.
Una chiave API di Google dentro una pagina web è ciò che fa funzionare Google Maps. La chiave dice quale progetto paga, e ciò che impedisce a uno sconosciuto di spendere a tue spese è la restrizione sulla chiave invece della sua segretezza. La guida di Google è netta su entrambe le metà: "Unrestricted API keys are insecure", e "You are financially responsible for charges caused by abuse of unrestricted API keys." La riparazione per una chiave del genere consiste nell'aprirla nella Cloud Console e aggiungere due restrizioni, una che nomina il tuo sito e una che nomina le API che chiami davvero. La chiave in sé non cambia mai.
L'altra famiglia che sta nel browser sono le chiavi pubblicabili. Una chiave
Stripe pk_live_, e una Supabase sb_publishable_ o anon, sono fatte perché
le legga ogni visitatore che hai.
Quali chiavi sono sicure nel frontend
è la versione in quattro caratteri di quella prova.
Se preferisci non passare il bundle a mano, la nostra scansione gratuita legge il tuo sito online, elenca le chiavi che vede dall'esterno e dice di che tipo è ciascuna: scansiona la tua app. Richiede una ventina di secondi e non chiede alcun account.
La mia chiave API è trapelata. Cosa faccio per prima cosa?
Stabilisci se la chiave ha un contatore.
Una chiave con contatore ti addebita ogni richiesta. Quella di Google, quella di
OpenAI, quella di Anthropic e una chiave AWS con i permessi sbagliati dietro
sono tutti contatori: il traffico di qualcun altro atterra sulla tua fattura, a
un ritmo che sceglie quella persona e che tu non vedi. Una chiave senza
contatore legge o scrive invece i tuoi dati. Una chiave Supabase service_role
è l'esempio più chiaro, e niente in essa costa denaro all'ora.
Quella sola domanda fissa l'ordine.
Se la chiave ha un contatore, fermala adesso. La funzione che la usava resta rotta finché non pubblichi la sostituta, ed è lo scambio giusto, perché la fattura è l'unica parte di questa storia che continua a crescere mentre tu pianifichi.
Se la chiave legge dati ed è stata pubblicata nel tuo bundle, la lettura è già avvenuta. Ogni visitatore che ha caricato la pagina ne ha una copia, e così ogni crawler andato a cercare esattamente quella stringa. Nulla peggiora mentre ricostruisci l'ordine giusto, e la cosa da non sbagliare è non chiuderti fuori dalla tua stessa applicazione lungo la strada.
Cosa può fare davvero ogni tipo di chiave
| Chiave | Spende denaro | Legge i tuoi dati | Si può limitare invece di sostituirla? | Sostituirla rompe l'applicazione? |
|---|---|---|---|---|
Supabase sb_publishable_ o anon | No | Solo le righe che le tue regole permettono | Il suo posto è il browser | Non pertinente |
Stripe pk_live_ | No | No | Il suo posto è il browser | Non pertinente |
Google AIza… | Sì, sulla tua fattura Cloud | No | Sì, e Google dice di provare prima quello | Limitarla no. Ruotarla può. |
| Chiave OpenAI o Anthropic | Sì, al ritmo di uno sconosciuto | I file e gli assistant del progetto | Non esiste una variante pubblicabile | Sì, finché non la tiene un tuo server |
Stripe sk_live_ o rk_live_ | Sì | Sì, clienti e registri di pagamento | Una chiave ristretta è la versione stretta | No, c'è una finestra di sette giorni |
AWS AKIA… più la metà segreta | Sì, compreso calcolo a ore | I tuoi bucket S3 | Deactivate, ed è reversibile | No, puoi tenerne due alla volta |
Supabase sb_secret_ o service_role | No | Ogni riga di ogni tabella | No | Sì, su un progetto più vecchio |
Due note su quella tabella, perché entrambe cambiano cosa fai dopo.
Una chiave di accesso AWS sono due stringhe, un identificativo che comincia con
AKIA e una metà segreta, e AWS pretende entrambe insieme per firmare una
richiesta. Quindi una stringa AKIA da sola in un bundle non è utilizzabile, e
il motivo per trattarla comunque come urgente è che le due metà vengono quasi
sempre incollate insieme. Apri il file e cerca la seconda prima di decidere in
quale caso ti trovi.
Il dettaglio per fornitore sta presso ciascun fornitore: una chiave OpenAI, una chiave API di Google, una chiave segreta Stripe e una chiave service_role di Supabase, che è l'unica con una procedura tutta sua.
Fermare la chiave e sostituire la chiave sono due pulsanti diversi
Ogni fornitore di quella tabella te li dà entrambi, e chi è nel panico afferra il secondo.
- Google. Limitare una chiave non cambia la stringa, quindi la tua applicazione continua a funzionare. La loro guida di sicurezza mette questo prima di tutto il resto: "First try to restrict your API keys", e la rotazione è la terza opzione scendendo, per quando una restrizione non è possibile.
- Stripe. Expire key ferma una chiave da sola, senza nessuna sostituta di mezzo. La loro posizione su quando usarlo non ha sfumature: "If a restricted or secret API key is exposed or compromised, rotate it immediately even if you aren't sure anyone saw it." Separano anche le due parole che tutti usano come sinonimi. Exposure è che la chiave sia diventata visibile dove non doveva. Compromise è la prova che qualcuno l'ha usata.
- AWS. Deactivate è il comando, e la parte utile è che si può tornare indietro. AWS dice di non cancellare affatto la vecchia chiave finché stai ancora controllando: "we recommend that you do not immediately delete the first access key. Instead, choose Actions and then choose Deactivate." Se salta fuori che qualcosa che avevi dimenticato la usa ancora, la riaccendi.
- Supabase, su un progetto più vecchio. C'è un solo interruttore, e copre
entrambe le chiavi legacy.
anoneservice_rolesono firmate dallo stesso segreto, quindi disattivare quella che vuoi eliminare ferma anche quella che usa il tuo frontend. I quattro passi che lo evitano conviene leggerli prima di toccare l'interruttore, non dopo.
Leggere il log del periodo in cui la chiave è stata fuori
La finestra si apre con il deploy che ha pubblicato la chiave e si chiude quando l'hai fermata. È su quell'intervallo di date che filtri il log del fornitore.
Ogni fornitore della tabella ne tiene uno. Stripe mostra i log delle richieste di una singola chiave, dal menu a tre puntini accanto a quella chiave nella pagina delle API Keys. AWS mette una data di ultimo utilizzo su ogni chiave di accesso nella console IAM senza alcuna configurazione, e registra le chiamate stesse in CloudTrail. Google traccia l'uso per chiave nella Cloud Console, che è anche la lettura che la loro guida ti chiede di fare prima di cambiare qualsiasi cosa su una chiave. Supabase conserva log di API e di database per il progetto, e come restringere la finestra su una chiave Supabase dice cosa cercarvi dentro.
Quello che cerchi è traffico che non sai spiegare: richieste a tabelle o endpoint che la tua applicazione non tocca mai, volume in ore in cui nessuno la stava usando, cancellazioni che nessuno ha fatto. Poi guarda i dati stessi, perché un messaggio di assistenza su un record che è cambiato da solo è il modo in cui la maggior parte di questi casi viene davvero scoperta, e arriva settimane dopo.
Spesso non puoi averne la certezza, e Stripe dice altrettanto del proprio rilevamento: "Stripe doesn't guarantee detection of all exposed or compromised keys." Quindi "niente nel log" è un risultato, e vale la pena annotarlo con accanto l'intervallo di date.
Ruotare senza mettere giù l'applicazione
Tre dei quattro fornitori qui sopra ti lasciano una finestra in cui la vecchia e la nuova chiave funzionano entrambe, ed è ciò che evita il disservizio.
Stripe. "When you rotate a key in the Dashboard, both the old and new keys work for up to 7 days." La finestra di dialogo ha anche l'opzione Now, e la loro documentazione è esplicita: se la scegli, la vecchia chiave viene cancellata. È il pulsante dell'emergenza col contatore, non quello di una migrazione tranquilla. Il loro consiglio su quando lasciar andare la vecchia è una misura invece di una data: controlla i suoi log delle richieste e falla scadere solo dopo che il suo volume è rimasto a zero per qualche ora o qualche giorno.
Google. La rotazione crea la nuova chiave con tutte le restrizioni della vecchia e, nelle loro parole, "both the old and new key are accepted" durante la finestra in cui sposti le tue applicazioni. Se cancelli la vecchia troppo presto e qualcosa si rompe, c'è una via di ritorno: una chiave API di Google cancellata si può ripristinare entro 30 giorni.
AWS. La sequenza è nella loro documentazione e comincia dalla chiave nuova: crea la seconda chiave di accesso mentre la prima è ancora attiva, sposta ogni applicazione su di essa, controlla la data di ultimo utilizzo della vecchia, disattivala, e solo allora cancellala. Un tetto da mettere in conto: un utente IAM può tenere al massimo due chiavi di accesso, quindi una terza applicazione ancora su una vecchia chiave non ha dove andare.
Supabase, su un progetto più vecchio. Nessuna finestra. La rotazione diretta
delle chiavi legacy anon e service_role non è più supportata, quindi
invalidarne una è una migrazione alla nuova coppia di chiavi, e l'ordine dei
quattro passi è ciò che tiene in piedi l'applicazione.
È ancora nella tua cronologia Git
Lo è, e la documentazione di GitHub su questo comincia mandandoti da un'altra parte.
La loro pagina sulla rimozione dei dati sensibili ti rimanda alla chiave: "if the sensitive data you need to remove is a secret (e.g. password/token/credential), as is often the case, then as a first step you need to revoke and/or rotate that secret", e poi: "Once the secret is revoked or rotated, it can no longer be used for access, and that may be sufficient to solve your problem. Going through the extra steps to rewrite the history and remove the secret may not be warranted."
Il motivo che danno è ciò che un force push non raggiunge. Dopo che hai riscritto la cronologia, i vecchi commit sono ancora lì "In any clones or forks of your repository" e "Directly via their SHA-1 hashes in cached views on GitHub". L'assistenza può ripulire le viste in cache e i riferimenti nelle pull request se lo chiedi, e traccia una linea propria: "will only assist in the removal of sensitive data in cases where we determine that the risk can't be mitigated by rotating affected credentials." Un fork si tiene la sua copia in ogni caso, e GitHub non può darti i contatti di chi lo possiede.
Quindi l'ordine che descrivono è quello pratico: revocare la chiave e poi decidere se riscrivere la cronologia valga i suoi effetti collaterali. Revocare raggiunge copie che una riscrittura non raggiunge, compresa quella in un clone di cui non sai nulla e quella in uno screenshot che qualcuno ha tenuto.
Tenere la prossima fuori dal bundle
Una chiave entra nel tuo bundle attraverso un deploy, e i deploy continuano. Ognuno di essi è un'altra occasione perché un valore che hai messo in un pannello dei segreti finisca in un file che il browser scarica. È per questo che un controllo fatto il mese scorso descrive l'applicazione del mese scorso.
La nostra scansione gratuita risponde alla domanda con cui sei arrivato qui.
- i nove controlli sulla tua URL online, in una ventina di secondi
- ogni chiave che vede dall'esterno, classificata e non soltanto trovata
- un voto e i rilievi, senza account
Reeve Monitor rilancia quei controlli senza che tu lo chieda.
- tutti e nove i controlli ogni ora, su un massimo di tre applicazioni
- un messaggio quando un risultato cambia, così la chiave partita col deploy di stanotte non aspetta che tu vada a guardare
- se l'applicazione risponde, ogni 60 secondi
- un report mensile di quello che ha visto
Reeve Care conserva una copia del tuo database Supabase, per le chiavi che sanno scrivere.
- una copia cifrata ogni notte, tenuta dove il tuo progetto non arriva
- ogni copia verificata prima di contare, contando le righe di ogni tabella
- un ripristino con un clic quando ti serve
- anche i tuoi file caricati, appena colleghi una credenziale Storage
- tutto quello che fa Monitor
Una chiave trapelata che sa solo leggere lascia i tuoi dati dove erano. Una
chiave service_role, o una chiave AWS con permessi di scrittura, può svuotare
una tabella, e nessuna rotazione successiva riporta indietro le righe.
Il giorno in cui un agente IA ha cancellato un database di produzione
racconta com'è vista da dentro.
Cosa fare adesso
Cosa fare
- Identifica la chiave prima di toccarla. Una chiave Supabase
anonosb_publishable_e una Stripepk_live_stanno dove devono stare, e delle 1.332 applicazioni in cui abbiamo trovato una chiave da segnalare, 1.142 avevano una chiave API di Google, che chiede una restrizione invece di una rotazione. - Chiediti se ha un contatore. Se le richieste di qualcun altro atterrano sulla tua fattura, ferma la chiave adesso e lascia che la funzione si rompa.
- Usa il comando che ferma tanto quanto quello che sostituisce: Expire key su Stripe, Deactivate su AWS, una restrizione per sito e per API su Google.
- Sostituiscila poi dentro la finestra del fornitore. Stripe ti dà sette giorni con entrambe le chiavi attive, Google le accetta entrambe mentre migri, e AWS ti lascia tenere due chiavi di accesso alla volta.
- Leggi il log del fornitore per il periodo fra il deploy e lo stop, e annota cosa hai trovato, compreso "niente".
- Lascia la cronologia Git per ultima. Una volta revocata la chiave, la guida di GitHub dice che riscrivere la cronologia può non valerne affatto la pena.
Se preferisci percorrere tutto questo come una lista, la checklist di sicurezza in 10 minuti copre questo argomento e le altre cose che conviene spegnere in un'applicazione appena lanciata.
FAQ
La mia chiave API è trapelata. Cosa faccio per prima cosa?
Stabilisci se la chiave può spendere soldi. Una chiave che ti addebita ogni richiesta ti sta costando qualcosa proprio adesso, quindi fermala subito e accetta che la funzione che la usa resti rotta per qualche minuto. Una chiave che legge soltanto dei dati, se era pubblica, è già stata letta: prenditi il tempo di fare la sostituzione in un ordine che non ti chiuda fuori dalla tua stessa applicazione.
Revocare o ruotare per primo?
Revocare per primo, se la chiave ha un contatore. Fermare la vecchia chiave ed emetterne una nuova sono due comandi separati presso ogni fornitore, e solo il primo chiude il buco. L'eccezione è una chiave che puoi limitare invece di sostituire: Google ti dice di provare una restrizione per sito e per API prima ancora di ruotare una chiave API di Google.
Come capisco se qualcuno ha usato la mia chiave?
Restringi la finestra al periodo fra il deploy che ha pubblicato la chiave e il momento in cui l'hai fermata, poi leggi il log del fornitore su quell'intervallo. Stripe mostra i log delle richieste per singola chiave, AWS mostra una data di ultimo utilizzo sulla chiave di accesso e registra le chiamate in CloudTrail, Google traccia l'uso per chiave, e Supabase conserva log di API e di database. Cerchi richieste verso cose che la tua applicazione non tocca mai e traffico in ore in cui nessuno la stava usando. Spesso non puoi averne la certezza, ed è un esito normale.
Ruotare la chiave romperà la mia applicazione?
Di solito no, se usi la finestra che il fornitore ti dà. Stripe tiene la vecchia e la nuova chiave attive insieme fino a sette giorni. Google emette la nuova chiave con le restrizioni della vecchia e accetta entrambe mentre migri. AWS ti lascia tenere due chiavi di accesso alla volta, quindi la nuova è già viva prima che la vecchia se ne vada. L'eccezione è un progetto Supabase più vecchio, dove l'interruttore che disattiva le chiavi legacy si porta via anche la chiave del frontend.
La chiave è nella mia cronologia Git. Basta cancellare il file?
No, e neanche riscrivere la cronologia è probabilmente la risposta. La documentazione di GitHub dice di revocare o ruotare il segreto per primo, e che una volta fatto, mettersi a riscrivere la cronologia può non valerne la pena. Un force push non raggiunge le copie nei fork e nei cloni, né le viste in cache raggiungibili dall'hash del commit. Rendere la chiave inutilizzabile copre tutte le copie in una volta.