[{"data":1,"prerenderedAt":712},["ShallowReactive",2],{"blog-it-openai-api-key-exposed-in-frontend":3,"blog-index-it":470},{"id":4,"title":5,"body":6,"category":427,"cover":428,"coverAlt":429,"description":430,"draft":431,"extension":432,"faq":433,"image":449,"keywords":450,"meta":456,"navigation":457,"ogTitle":458,"path":459,"published":460,"seo":461,"stem":462,"tldr":463,"updated":468,"__hash__":469},"blog_it\u002Fblog\u002Fopenai-api-key-exposed-in-frontend.md","La tua chiave API OpenAI è esposta nel frontend. Ruotala.",{"type":7,"value":8,"toc":413},"minimark",[9,18,26,35,40,43,54,57,60,64,67,82,96,99,103,106,114,117,123,130,133,139,150,153,157,160,163,166,169,173,176,179,184,187,213,216,219,223,241,244,247,252,347,350,366,370,396],[10,11,12,13,17],"p",{},"Apri la tua app in un browser, guarda il sorgente della pagina e cercaci dentro\n",[14,15,16],"code",{},"sk-proj-",". Se torna una stringa lunga, la tua chiave API OpenAI è esposta nel\ntuo frontend, e qualsiasi visitatore tu abbia mai avuto avrebbe potuto copiarla.",[10,19,20,21,25],{},"Ecco la parte che quasi tutti i consigli su questo tema sbagliano: ",[22,23,24],"strong",{},"una chiave\nOpenAI non è una chiave Google con un prefisso diverso, e non c'è niente che tu\npossa impostare in una dashboard per renderla sicura dov'è."," Una chiave Google\nMaps sta bene nella tua pagina, e una impostazione gratuita la protegge. Una\nchiave OpenAI non ha da nessuna parte una impostazione equivalente, ed è per\nquesto che l'unica prima istruzione onesta è ruotarla.",[10,27,28,29,34],{},"Fra il 12 e il 14 agosto 2026 abbiamo eseguito nove controlli esterni su 30.998\napp online, costruite con Lovable, Bolt, v0, Replit e Base44. Una chiave OpenAI è\ncomparsa in 33 di esse. Tutte e 33 sono tornate con voto D o F, perché un solo\nriscontro critico mette un tetto al voto qualunque cosa l'app abbia fatto bene\nper il resto. I numeri completi sono nel\n",[30,31,33],"a",{"href":32},"\u002Fresearch\u002Fvibe-coded-app-security-2026","nostro rapporto di scansione",".",[36,37,39],"h2",{"id":38},"una-chiave-api-openai-esposta-nel-frontend-è-un-problema","Una chiave API OpenAI esposta nel frontend è un problema?",[10,41,42],{},"Sì. Questo è il caso in cui l'allarme ha ragione.",[10,44,45,46,49,50,53],{},"Una chiave OpenAI è un ",[22,47,48],{},"token al portatore",", e la parola contiene tutta la\nspiegazione: chi la porta può usarla. Viaggia in un header che recita\n",[14,51,52],{},"Authorization: Bearer sk-proj-…",", e i server di OpenAI non chiedono altro. Non\nquale sito l'ha mandata. Non da quale paese è arrivata, né se il mittente sei tu.",[10,55,56],{},"Pensa a un biglietto del treno e non a un passaporto. Un controllore non verifica\na quale nome è intestato un biglietto, perché averlo è tutta la qualifica. È\nquesto che rende un biglietto degno di essere rubato e un passaporto quasi mai.",[10,58,59],{},"Quindi una chiave stampata nella tua app è un biglietto che hai consegnato a ogni\nvisitatore. La maggior parte non guarderà mai. Chi guarda di solito non è\nnemmeno una persona: scraper automatici setacciano le pagine pubbliche\nraccogliendo stringhe a forma di chiave, e non hanno bisogno di sapere chi sei\nper trovare la tua.",[36,61,63],{"id":62},"perché-la-variabile-dambiente-non-lha-nascosta","Perché la variabile d'ambiente non l'ha nascosta",[10,65,66],{},"Perché una build di frontend compila le variabili d'ambiente dentro il file che\nspedisce.",[10,68,69,70,73,74,77,78,81],{},"È questo il passaggio che convince le persone che la chiave sia al sicuro. L'hai\ntolta dal codice e messa in un file ",[14,71,72],{},".env",", l'hai chiamata ",[14,75,76],{},"VITE_OPENAI_API_KEY","\no ",[14,79,80],{},"NEXT_PUBLIC_OPENAI_API_KEY",", e ora il codice nomina una variabile dove prima\nstava la chiave. Nell'app spedita non è cambiato nulla. Lo strumento di build ha\nsostituito quella variabile con il suo valore in uscita, e il valore è lì nel\nJavaScript che il tuo visitatore scarica.",[10,83,84,85,88,89,91,92,95],{},"La documentazione di Vite lo dice chiaramente: le variabili con il prefisso\n",[14,86,87],{},"VITE_"," sono esposte nel codice sorgente lato client dopo il bundling, e le\ninformazioni sensibili come le chiavi API non devono stare in una di esse, perché\ni valori vengono impacchettati dentro il tuo sorgente. I prefissi ",[14,90,87],{}," e\n",[14,93,94],{},"NEXT_PUBLIC_"," non sono una cassaforte. Sono una dichiarazione che hai capito che\nquella variabile è pubblica.",[10,97,98],{},"Una variabile d'ambiente una cosa vera per te l'ha fatta: ha tenuto la chiave\nfuori dal tuo repository, dove l'avrebbe incontrata chiunque leggesse il tuo\ncodice. I tuoi visitatori il tuo codice non lo leggono mai. Leggono il file che\nla tua build ne ha ricavato.",[36,100,102],{"id":101},"perché-non-puoi-limitarla-come-limiti-una-chiave-google","Perché non puoi limitarla come limiti una chiave Google",[10,104,105],{},"Perché OpenAI non offre una restrizione di quel tipo.",[10,107,108,109,113],{},"Se hai letto qualcosa su una chiave API Google in un frontend, hai incontrato una\nsoluzione da cinque minuti: apri la chiave nella console di Google Cloud, imposta\nuna restrizione di referrer HTTP, e la chiave stampata nella tua pagina funziona\nsul tuo sito e restituisce un errore ovunque altrove.\n",[30,110,112],{"href":111},"\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend","Quel consiglio è giusto per una chiave Google",",\ne non si trasferisce.",[10,115,116],{},"Su una chiave OpenAI non esiste alcun campo per \"solo da yourapp.com\". Nessuna\nlista di domini consentiti, nessun controllo del referrer, nessuna restrizione\nper IP che sopravviva a un browser. Quello che OpenAI ti dà al suo posto sta\nsull'account dietro la chiave: a quale progetto appartiene, quanto quel progetto\npuò spendere in un mese e se la chiave esiste ancora. Questo limita quanto può\ncostare una chiave rubata. La chiave stessa continua a funzionare da ovunque\nfinché non la cancelli.",[118,119],"diagram",{"alt":120,"caption":121,"src":122},"Due corsie. Nella corsia superiore una chiave Google parte da due siti diversi e incontra una barriera piena: la richiesta da yourapp.com la attraversa e raggiunge Google, quella da other.example viene fermata e segnata con una croce. Nella corsia inferiore una chiave OpenAI parte dagli stessi due siti, non c'è nessuna barriera disegnata, ed entrambe le richieste raggiungono api.openai.com.","La corsia superiore è la soluzione di cui si parla alla gente. In quella inferiore non c'è nulla da disegnare, perché OpenAI non ha nessuna impostazione di quella forma.","\u002Fblog\u002Fopenai-api-key-exposed-in-frontend\u002Fno-gate-to-set-1600x820.png",[36,124,126,127],{"id":125},"cosa-fa-davvero-dangerouslyallowbrowser","Cosa fa davvero ",[14,128,129],{},"dangerouslyAllowBrowser",[10,131,132],{},"Spegne una protezione, e il suo nome è la documentazione.",[10,134,135,136,138],{},"La libreria JavaScript ufficiale di OpenAI si rifiuta di girare in un browser per\nimpostazione predefinita. Il README dice che il supporto al browser è\n\"disabled by default to avoid exposing your secret API credentials\", e che\nattivare ",[14,137,129],{}," \"can be dangerous because it exposes your\nsecret API credentials in the client-side code\".",[10,140,141,142,145,146,149],{},"Se la tua app chiama OpenAI dal browser, quell'opzione è impostata a ",[14,143,144],{},"true"," da\nqualche parte nel tuo codice, perché la libreria senza non parte. Qualcuno ha\ndigitato la parola ",[14,147,148],{},"dangerously"," per far sparire un messaggio di errore. Di\nsolito è così che questo riscontro viene prodotto, e la libreria te lo aveva\ndetto per prima.",[10,151,152],{},"L'opzione ha usi reali, e sono tutti stretti: uno strumento interno dove conosci\nogni utente, una chiave di sviluppo temporanea, una chiave così limitata che\nspenderla non costa nulla. Un'app pubblica su internet aperto non è nessuno di\nquesti.",[36,154,156],{"id":155},"quanto-costa-che-qualcuno-trovi-la-tua-chiave","Quanto costa che qualcuno trovi la tua chiave",[10,158,159],{},"Una fattura, e un'app che smette di funzionare.",[10,161,162],{},"La fattura è la parte che le persone si aspettano. Le richieste di qualcun altro\nvengono addebitate al tuo account, e le chiamate a un modello non sono economiche\nper gli standard di un progetto secondario. Di solito chi gestisce l'app se ne\naccorge da una fattura più alta di quella del mese prima senza un motivo che\npossa indicare.",[10,164,165],{},"Il fermo è la parte che non si aspetta. Il tuo account ha limiti di frequenza, e\nil traffico di uno sconosciuto se li mangia. La tua app comincia a restituire\nerrori nelle ore in cui qualcun altro sta lavorando, e questo si legge come un\nbug e non come un furto, così si passa una giornata a fare debug della cosa\nsbagliata.",[10,167,168],{},"C'è un terzo costo, e dipende da come era limitata la chiave. Una chiave API\nautentica ogni chiamata che il progetto a cui appartiene può fare, quindi una\nchiave con permessi ampi raggiunge tutto il resto che è archiviato lì: i file\ncaricati sull'account, i modelli affinati, gli assistenti che hai costruito.\nVerifica cosa poteva davvero raggiungere la chiave prima di decidere che qui si\ntrattava solo di soldi.",[36,170,172],{"id":171},"come-chiamare-openai-dalla-tua-app-senza-spedire-la-chiave","Come chiamare OpenAI dalla tua app senza spedire la chiave",[10,174,175],{},"Metti qualcosa di tuo fra il tuo visitatore e OpenAI.",[10,177,178],{},"La forma è la stessa ovunque. La tua app chiama un piccolo endpoint che è tuo.\nQuell'endpoint tiene la chiave, chiama OpenAI e restituisce la risposta. Il\nbrowser la chiave non la vede mai, perché la chiave non lascia mai il tuo server.",[118,180],{"alt":181,"caption":182,"src":183},"Due righe. Nella riga in alto un pannello del browser contiene un valore di chiave in rosso e una linea parte da lì diretta verso api.openai.com. Nella riga in basso il pannello del browser non contiene alcuna chiave, una linea arriva a un riquadro server che tiene la chiave in verde acqua, e una seconda linea prosegue dal server verso api.openai.com.","La stessa richiesta in entrambe le righe. Quello che cambia è da che parte del tuo server sta la chiave.","\u002Fblog\u002Fopenai-api-key-exposed-in-frontend\u002Fwho-holds-the-key-1600x720.png",[10,185,186],{},"Dove vive quell'endpoint dipende da cosa hai usato per costruire:",[188,189,190,197,207],"ul",{},[191,192,193,196],"li",{},[22,194,195],{},"Supabase nel tuo stack",": una Edge Function, con la chiave salvata come secret nella dashboard di Supabase.",[191,198,199,202,203,206],{},[22,200,201],{},"Deploy su Vercel o Netlify",": una funzione serverless sotto ",[14,204,205],{},"\u002Fapi",", con la chiave nelle variabili d'ambiente lato server del progetto.",[191,208,209,212],{},[22,210,211],{},"Lovable, Bolt o Replit",": ognuno ha un proprio archivio di secret. La regola non cambia, e nemmeno la trappola: un archivio etichettato secret manda comunque il valore al browser se il codice che lo legge gira lì.",[10,214,215],{},"Due cose che vale la pena fare già che ci sei. Dai al tuo endpoint un limite di\nfrequenza, perché un endpoint che chiama OpenAI per chiunque lo chieda è la\nstessa fattura per una via più lenta. E metti un limite di spesa mensile sul\nprogetto OpenAI, l'unico controllo che mette un pavimento sotto il caso peggiore.",[10,217,218],{},"Se la tua app usa la Realtime API di OpenAI per la voce, il browser una\ncredenziale gli serve davvero, e OpenAI documenta come dargliela: il tuo server\nconia un client secret a vita breve e passa quello alla pagina. Il biglietto\nesiste ancora, scade in pochi minuti, ed è stato il tuo server a emetterlo.",[36,220,222],{"id":221},"come-trovare-gratis-ogni-chiave-che-la-tua-app-spedisce","Come trovare gratis ogni chiave che la tua app spedisce",[10,224,225,226,228,229,232,233,236,237,240],{},"Comincia a mano, perché costa cinque minuti e non richiede di installare nulla.\nGuarda il sorgente del tuo sito in produzione e cercaci ",[14,227,16],{}," per una chiave\nOpenAI, ",[14,230,231],{},"sk-ant-"," per una di Anthropic, ",[14,234,235],{},"AIza"," per Google e ",[14,238,239],{},"eyJ"," per un token\nSupabase.",[10,242,243],{},"Quello che così sfugge è il JavaScript che la pagina carica dopo, che su un'app\nvibe-coded è quasi tutto. Il nostro scanner apre la tua app in un browser vero,\naspetta che arrivino i bundle e legge quelli al posto dell'HTML. Decodifica anche\nogni token Supabase e riporta il ruolo scritto dentro, così una chiave che nella\ntua pagina ci sta torna segnata come corretta e non sepolta in un muro di rosso.",[10,245,246],{},"Il controllo delle chiavi è uno di nove, e gli altri otto sono il motivo per cui\nun voto ti dice più di una ricerca:",[118,248],{"alt":249,"caption":250,"src":251},"Il marchio Reeve sopra una fila di nove icone a contorno, una per controllo: una chiave, un cilindro di database, un documento, un lucchetto, una scatola con coperchio, una coppia di parentesi di codice, un globo, una coccarda di certificato e un calendario.","I nove controlli in sola lettura che esegue una scansione, nell'ordine dell'elenco qui sotto. Ognuno viene letto da fuori, come vede la tua app uno sconosciuto.","\u002Fblog\u002Fopenai-api-key-exposed-in-frontend\u002Fnine-checks-1600x420.png",[253,254,255,268],"table",{},[256,257,258],"thead",{},[259,260,261,265],"tr",{},[262,263,264],"th",{},"Cosa guarda la scansione",[262,266,267],{},"La domanda a cui risponde",[269,270,271,280,288,299,307,315,323,331,339],"tbody",{},[259,272,273,277],{},[274,275,276],"td",{},"Chiavi segrete nel tuo codice",[274,278,279],{},"C'è una chiave API a pagamento o di admin leggibile da chiunque?",[259,281,282,285],{},[274,283,284],{},"Regole del database",[274,286,287],{},"Uno sconosciuto può leggere le righe dei tuoi utenti senza login?",[259,289,290,293],{},[274,291,292],{},"File privati",[274,294,295,296,298],{},"File ",[14,297,72],{}," o dump del database sono scaricabili da un URL?",[259,300,301,304],{},[274,302,303],{},"Header di sicurezza",[274,305,306],{},"Le protezioni lato browser sono attive?",[259,308,309,312],{},[274,310,311],{},"Bucket di storage",[274,313,314],{},"Chiunque può elencare i file caricati dai tuoi utenti?",[259,316,317,320],{},[274,318,319],{},"Source map",[274,321,322],{},"Il tuo codice sorgente originale è pubblicato accanto all'app?",[259,324,325,328],{},[274,326,327],{},"API aperte e CORS",[274,329,330],{},"I tuoi endpoint rispondono a qualsiasi sito che chieda?",[259,332,333,336],{},[274,334,335],{},"Scadenza del certificato",[274,337,338],{},"L'HTTPS è valido e non sta per scadere addosso ai visitatori?",[259,340,341,344],{},[274,342,343],{},"Rinnovo del dominio",[274,345,346],{},"Il nome è rinnovato prima che qualcun altro possa prenderselo?",[10,348,349],{},"Ottieni un voto, un punteggio e i conteggi sullo schermo in circa 20 secondi,\nsenza account. Dai un indirizzo email e insieme arriva anche l'elenco\ndettagliato, con una correzione scritta per il tuo builder che puoi incollare\ncosì com'è.",[10,351,352,353,356,357,361,362,34],{},"Tre cose che non farà, e sono i motivi per cui è sicuro puntarlo su un'app in\nproduzione: non fa mai il login, non scrive mai nulla e non conserva mai una\nchiave che trova. Un segreto esposto viene salvato come suggerimento mascherato\nnella forma ",[14,354,355],{},"sk-proj-…a1b2",", e il valore vero viene buttato.\n",[30,358,360],{"href":359},"\u002F#scan","Scansiona la tua app",", oppure leggi prima\n",[30,363,365],{"href":364},"\u002Fsecurity-scanner","cosa guarda ognuno dei nove controlli",[36,367,369],{"id":368},"cosa-fare-adesso","Cosa fare adesso",[371,372,373],"key-takeaways",{},[188,374,375,378,381,384,387],{},[191,376,377],{},"Ruota la chiave per prima cosa, nella dashboard di OpenAI sotto API keys. Toglierla dal codice non chiude niente, perché il vecchio valore resta nella tua cronologia delle versioni e in ogni copia in cache della tua pagina.",[191,379,380],{},"Metti un limite di spesa mensile sul progetto a cui appartiene la chiave. È l'unico controllo che mette un tetto a quanto questo errore, o uno successivo, può costarti.",[191,382,383],{},"Sposta la chiamata dietro un endpoint tuo, e dai a quell'endpoint un suo limite di frequenza. Un browser non dovrebbe mai tenere una chiave che spende soldi.",[191,385,386],{},"Leggi la pagina dei consumi per i giorni in cui la chiave era attiva. Ruotare ferma quello che succede da adesso e non dice nulla su quello che è già successo.",[191,388,389,390,392,393,395],{},"Tieni un prefisso ",[14,391,87],{}," o ",[14,394,94],{}," lontano da tutto ciò che ti dispiacerebbe far leggere a uno sconosciuto. Quei prefissi vogliono dire pubblico, e il tuo strumento di build li prende in parola.",[10,397,398,399,403,404,408,409,34],{},"Se preferisci affrontare tutto in una volta sola, la\n",[30,400,402],{"href":401},"\u002Fchecklist","checklist di sicurezza in 10 minuti"," copre questo insieme alle altre\ncose da chiudere in un'app appena lanciata. E per la domanda più ampia su quali\nchiavi stiano bene in un browser, abbiamo\n",[30,405,407],{"href":406},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","una guida per distinguere le chiavi pubblicabili da quelle segrete","\ne\n",[30,410,412],{"href":411},"\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps","un censimento di cosa hanno davvero spedito 30.998 app",{"title":414,"searchDepth":415,"depth":415,"links":416},"",3,[417,419,420,421,423,424,425,426],{"id":38,"depth":418,"text":39},2,{"id":62,"depth":418,"text":63},{"id":101,"depth":418,"text":102},{"id":125,"depth":418,"text":422},"Cosa fa davvero dangerouslyAllowBrowser",{"id":155,"depth":418,"text":156},{"id":171,"depth":418,"text":172},{"id":221,"depth":418,"text":222},{"id":368,"depth":418,"text":369},"Basi della sicurezza","\u002Fblog\u002Fopenai-api-key-exposed-in-frontend\u002Fcover-1200x630.png","Un valore a forma di chiave dentro una pagina di codice di un'app, disegnato tanto lungo da uscire dal bordo destro del pannello che lo contiene.","Una chiave API OpenAI esposta nel frontend non si può legare a nessun dominio. Ruotala oggi, sposta la chiamata sul tuo server e metti un tetto di spesa.",false,"md",[434,437,440,443,446],{"q":435,"a":436},"Qualcuno ha trovato la mia chiave OpenAI nella mia app. Qual è la prima cosa da fare?","Ruotarla. Apri la dashboard di OpenAI in API keys, crea una chiave nuova, metti quella nuova sul tuo server e cancella la vecchia. Toglierla dal codice non è la stessa cosa, perché il vecchio valore resta nella tua cronologia delle versioni e in ogni copia in cache della tua pagina. Poi metti un limite di spesa sul progetto e leggi la pagina dei consumi per i giorni in cui la chiave era attiva.",{"q":438,"a":439},"Posso limitare una chiave OpenAI al mio dominio, come faccio con una di Google?","No. Una chiave API Google accetta una restrizione di referrer HTTP che la fa funzionare sul tuo sito e fallire ovunque altrove, ed è per questo che una chiave Google nella tua pagina di solito non è un problema. OpenAI non offre nulla di equivalente. Non esiste né una lista di domini consentiti né un controllo del referrer su una chiave API, quindi gli unici controlli che hai stanno sull'account dietro di essa: a quale progetto appartiene la chiave, quanto quel progetto può spendere e se la chiave esiste ancora.",{"q":441,"a":442},"La libreria di OpenAI ha un'opzione dangerouslyAllowBrowser. La rende sicura?","No, e il nome è l'avvertimento. OpenAI consegna il supporto al browser disattivato, e il suo stesso README dice che l'opzione è pericolosa perché espone le tue credenziali API segrete nel codice lato client. Attivarla non cambia ciò che il browser può leggere; impedisce soltanto alla libreria di rifiutarsi di partire. I casi stretti per cui è pensata sono strumenti interni con utenti noti e chiavi di sviluppo a vita breve, non un'app pubblica.",{"q":444,"a":445},"Quanto può spendere qualcuno con una chiave che ha trovato?","Quanto il tuo account consente, ed è per questo che il limite di spesa conta più della fattura che hai visto finora. Una chiave rubata attinge agli stessi limiti di frequenza che usa la tua app, quindi il primo sintomo spesso non è la fattura: è la tua app che comincia a fallire mentre qualcun altro sta lavorando. Metti un limite di spesa mensile sul progetto e hai un tetto su tutto questo.",{"q":447,"a":448},"Ho usato la chiave solo per una demo veloce. Conta lo stesso?","Sì. Una chiave resta attiva finché qualcuno non la revoca, e non sa di dover essere temporanea. Gli scraper automatici raccolgono di continuo stringhe a forma di chiave dalle pagine pubbliche, quindi l'età della demo gioca contro di te e non a tuo favore. Cancellare la chiave richiede meno tempo che decidere se valeva la pena cancellarla.","\u002Fblog\u002Fopenai-api-key-exposed-in-frontend\u002Fcard-800x500.png",[451,452,453,454,129,455],"chiave api openai esposta frontend","nascondere chiave api openai in react","chiamare openai dal frontend in sicurezza","sicurezza della chiave api openai","chiave api openai trapelata",{},true,"Chiave API OpenAI esposta nel tuo frontend?","\u002Fblog\u002Fopenai-api-key-exposed-in-frontend","2026-09-03",{"title":5,"description":430},"blog\u002Fopenai-api-key-exposed-in-frontend",[464,465,466,467],"Una chiave API OpenAI esposta nel tuo frontend è il caso in cui l'allarme ha ragione. Nessuna impostazione rende sicura una chiave del genere dentro un browser.","È un token al portatore, quindi basta averla in mano. Non esiste una restrizione di dominio che la leghi al tuo sito, come invece esiste per una chiave Google.","Ruotala oggi nella dashboard di OpenAI, sposta la chiamata dietro un endpoint tuo e metti un limite di spesa sul progetto.","Ne abbiamo trovata una in 33 app su 30.998 scansionate. Rara, e tutte e 33 sono uscite con voto D o F.","2026-09-21","8KXP1ajTycLrPSSaHajtU5S-QnFChYDkbHRw-yiLSaU",[471,478,484,489,495,501,507,513,519,525,531,537,543,549,555,561,567,573,579,585,591,592,597,603,609,615,621,627,633,639,645,651,657,662,668,674,679,685,691,697,702,708],{"path":472,"title":473,"description":474,"published":475,"category":476,"image":477,"draft":431},"\u002Fblog\u002Fsupabase-backup-auth-users","Perché nel tuo dump Supabase non ci sono utenti","Lancia supabase db dump da solo e ottieni la forma del tuo database e nessuna delle sue righe, senza lo schema auth in cui vivono i tuoi utenti.","2026-09-23","Backups","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",{"path":479,"title":480,"description":481,"published":482,"category":427,"image":483,"draft":431},"\u002Fblog\u002Fdomain-and-certificate-expiry","Dominio scaduto, sito offline: cosa succede adesso","Il tuo dominio è scaduto e il sito è offline. Il conto alla rovescia che parte, perché il certificato è il problema minore, e come controllarli entrambi.","2026-09-22","\u002Fblog\u002Fdomain-and-certificate-expiry\u002Fcard-800x500.png",{"path":485,"title":486,"description":487,"published":468,"category":427,"image":488,"draft":431},"\u002Fblog\u002Fis-lovable-safe","Lovable è sicuro? Cosa abbiamo trovato in 18.554 app Lovable","Lovable è sicuro? Abbiamo passato 18.554 app Lovable online per nove controlli. La piattaforma è risultata la più pulita di cinque. I rilievi stavano nelle app.","\u002Fblog\u002Fis-lovable-safe\u002Fcard-800x500.png",{"path":490,"title":491,"description":492,"published":493,"category":427,"image":494,"draft":431},"\u002Fblog\u002Fvibe-coded-app-security-checklist","La checklist di sicurezza del vibe coding, in nove controlli","Una checklist di sicurezza del vibe coding in nove voci, ognuna verificabile dall’esterno sulla tua app dal vivo, e ognuna con un test di una riga.","2026-09-20","\u002Fblog\u002Fvibe-coded-app-security-checklist\u002Fcard-800x500.png",{"path":496,"title":497,"description":498,"published":499,"category":427,"image":500,"draft":431},"\u002Fblog\u002Fstripe-secret-key-in-frontend","Una chiave segreta Stripe nel frontend può muovere denaro","Una chiave segreta Stripe esposta nel tuo frontend può rimborsare, addebitare e leggere ogni scheda cliente che hai. La tua chiave pk_live_ ci sta bene.","2026-09-19","\u002Fblog\u002Fstripe-secret-key-in-frontend\u002Fcard-800x500.png",{"path":502,"title":503,"description":504,"published":505,"category":427,"image":506,"draft":431},"\u002Fblog\u002Fvite-and-next-public-env-vars","Variabili d’ambiente Vite esposte: il prefisso vuol dire pubblica","Variabili d’ambiente Vite esposte: la tua app ha fatto ciò che il prefisso chiedeva. VITE_ e NEXT_PUBLIC_ vogliono dire pubblica, e l’IA non sapeva il costo.","2026-09-18","\u002Fblog\u002Fvite-and-next-public-env-vars\u002Fcard-800x500.png",{"path":508,"title":509,"description":510,"published":511,"category":427,"image":512,"draft":431},"\u002Fblog\u002Fbase44-source-maps","Sicurezza Base44: cosa segnala uno scan e cosa tocca a te sistemare","Sicurezza Base44 su 5.438 app scansionate: tre segnalazioni su quasi tutte sono della piattaforma, la source map è il badge di Base44, la tua parte è corta.","2026-09-17","\u002Fblog\u002Fbase44-source-maps\u002Fcard-800x500.png",{"path":514,"title":515,"description":516,"published":517,"category":427,"image":518,"draft":431},"\u002Fblog\u002Fis-cursor-ai-safe","Cursor AI è sicuro? L’editor, il codice e l’app che hai pubblicato","Cursor AI è sicuro? Tre domande in una ricerca: cosa tiene Cursor, cosa sbaglia il codice che scrive, e se l’app che hai pubblicato è aperta.","2026-09-16","\u002Fblog\u002Fis-cursor-ai-safe\u002Fcard-800x500.png",{"path":520,"title":521,"description":522,"published":523,"category":427,"image":524,"draft":431},"\u002Fblog\u002Fis-replit-safe","Replit è sicuro? Cosa abbiamo trovato in 3.042 app Replit online","Replit è sicuro? Abbiamo passato 3.042 app Replit online per nove controlli esterni. I rilievi stavano nell’app pubblicata, non nell’host.","2026-09-15","\u002Fblog\u002Fis-replit-safe\u002Fcard-800x500.png",{"path":526,"title":527,"description":528,"published":529,"category":476,"image":530,"draft":431},"\u002Fblog\u002Fsupabase-storage-backup","Supabase storage backup: la copia del database non ha nessun file","Un Supabase storage backup è un lavoro a parte. I backup del database tengono la lista dei tuoi file e nessuno dei file, quindi ogni upload resta rotto.","2026-09-14","\u002Fblog\u002Fsupabase-storage-backup\u002Fcard-800x500.png",{"path":532,"title":533,"description":534,"published":535,"category":476,"image":536,"draft":431},"\u002Fblog\u002Fsupabase-point-in-time-recovery","Point-in-time recovery di Supabase: prezzo e limiti","Il point-in-time recovery di Supabase riavvolge il database a qualsiasi secondo della settimana scorsa. $100 al mese oltre a Pro, e copre solo il database.","2026-09-13","\u002Fblog\u002Fsupabase-point-in-time-recovery\u002Fcard-800x500.png",{"path":538,"title":539,"description":540,"published":541,"category":476,"image":542,"draft":431},"\u002Fblog\u002Fsupabase-project-paused-recover","Progetto Supabase in pausa? I tuoi dati sono ancora lì","Supabase ha messo in pausa il tuo progetto dopo una settimana senza attività. Non è cancellato niente, Ripristina è accanto al nome e hai un anno di tempo.","2026-09-12","\u002Fblog\u002Fsupabase-project-paused-recover\u002Fcard-800x500.png",{"path":544,"title":545,"description":546,"published":547,"category":427,"image":548,"draft":431},"\u002Fblog\u002Fsafest-ai-app-builder","Qual è il builder di app con IA più sicuro? 30.998 app testate","Qual è il builder di app con IA più sicuro? Abbiamo scansionato 30.998 app online di Lovable, Base44, Replit, v0 e Bolt. Non è il builder a decidere il voto.","2026-09-11","\u002Fblog\u002Fsafest-ai-app-builder\u002Fcard-800x500.png",{"path":550,"title":551,"description":552,"published":553,"category":427,"image":554,"draft":431},"\u002Fblog\u002Fenable-rls-on-every-supabase-table","Attiva Row Level Security su ogni tabella Supabase, poi verificalo","Attivare Row Level Security su Supabase senza una policy chiude del tutto la tabella. Una policy senza il flag non fa nulla. Ecco lo SQL, e la verifica.","2026-09-10","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fcard-800x500.png",{"path":556,"title":557,"description":558,"published":559,"category":427,"image":560,"draft":431},"\u002Fblog\u002Fsupabase-rls-disabled-in-public","Supabase \"RLS disabled in public\": cosa non vede l'avviso","Supabase segnala \"RLS disabled in public\" come errore. Non dice nulla della policy di lettura che lascia la tua tabella altrettanto aperta.","2026-09-09","\u002Fblog\u002Fsupabase-rls-disabled-in-public\u002Fcard-800x500.png",{"path":562,"title":563,"description":564,"published":565,"category":427,"image":566,"draft":431},"\u002Fblog\u002Frotate-supabase-service-role-key","Come ruotare una chiave service_role Supabase trapelata","Supabase dice di chiudere prima la falla. Altre guide dicono di ruotare subito. Quale sia giusto dipende da dove è finita la tua chiave service_role.","2026-09-08","\u002Fblog\u002Frotate-supabase-service-role-key\u002Fcard-800x500.png",{"path":568,"title":569,"description":570,"published":571,"category":427,"image":572,"draft":431},"\u002Fblog\u002Fvibe-coding-security-scanners-compared","Scanner di sicurezza per vibe coding a confronto, il nostro incluso","Il miglior scanner di sicurezza per vibe coding dipende da tre domande che nessun elenco di funzioni affronta. Dieci strumenti a confronto, con i prezzi.","2026-09-07","\u002Fblog\u002Fvibe-coding-security-scanners-compared\u002Fcard-800x500.png",{"path":574,"title":575,"description":576,"published":577,"category":427,"image":578,"draft":431},"\u002Fblog\u002Fsupabase-security-checker","Supabase security checker: i cinque controlli da fare da soli","Un Supabase security checker legge la tua app pubblicata invece delle impostazioni del progetto. Ecco i cinque controlli che esegue e come farli da solo.","2026-09-06","\u002Fblog\u002Fsupabase-security-checker\u002Fcard-800x500.png",{"path":580,"title":581,"description":582,"published":583,"category":427,"image":584,"draft":431},"\u002Fblog\u002Fvibe-coding-security-scanner","Scanner di sicurezza per vibe coding: cosa si perde","Uno scanner di sicurezza per vibe coding legge la tua app dal vivo, da fuori. Cosa copre, le quattro cose che non può vedere e come leggere il risultato.","2026-09-05","\u002Fblog\u002Fvibe-coding-security-scanner\u002Fcard-800x500.png",{"path":586,"title":587,"description":588,"published":589,"category":427,"image":590,"draft":431},"\u002Fblog\u002Fmissing-security-headers","Intestazioni di sicurezza mancanti: quando contano","Le intestazioni di sicurezza mancanti sono il rilievo che il nostro scanner stampa più spesso. Da cosa proteggono e quando sono la riga meno urgente.","2026-09-04","\u002Fblog\u002Fmissing-security-headers\u002Fcard-800x500.png",{"path":459,"title":5,"description":430,"published":460,"category":427,"image":449,"draft":431},{"path":411,"title":593,"description":594,"published":595,"category":427,"image":596,"draft":431},"Chiave API esposta nel frontend: cosa spediscono 30.998 app","Una chiave API esposta nel tuo frontend è quasi sempre una chiave di Google Maps. Abbiamo scansionato 30.998 app vibe-coded e contato cosa esce davvero.","2026-09-02","\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps\u002Fcard-800x500.png",{"path":598,"title":599,"description":600,"published":601,"category":476,"image":602,"draft":431},"\u002Fblog\u002Fsupabase-backup-tools-compared","Strumenti di backup Supabase a confronto, il nostro incluso","Quattro tipi di strumento di backup Supabase, cosa copia davvero ognuno, e il caso in cui una GitHub Action gratuita batte il pagare chiunque, noi inclusi.","2026-09-01","\u002Fblog\u002Fsupabase-backup-tools-compared\u002Fcard-800x500.png",{"path":604,"title":605,"description":606,"published":607,"category":427,"image":608,"draft":431},"\u002Fblog\u002Freplit-secrets-explained","Come usare i secret su Replit, e cosa viene comunque pubblicato","Come usare i secret su Replit: aggiungerne uno, rileggerlo e risolvere le due cause dell'undefined. E le chiavi che lo strumento non riesce a proteggere.","2026-08-31","\u002Fblog\u002Freplit-secrets-explained\u002Fcard-800x500.png",{"path":610,"title":611,"description":612,"published":613,"category":476,"image":614,"draft":431},"\u002Fblog\u002Fback-up-supabase-free-tier","Backup del piano gratuito Supabase: farne uno senza terminale","Sul piano gratuito Supabase non esistono backup: la copia la fai tu. Come farne uno dalla dashboard e che cosa si lascia dietro la via del CSV.","2026-08-30","\u002Fblog\u002Fback-up-supabase-free-tier\u002Fcard-800x500.png",{"path":616,"title":617,"description":618,"published":619,"category":427,"image":620,"draft":431},"\u002Fblog\u002Fis-supabase-secure","Supabase è sicuro? Sì. Il tuo progetto è un'altra questione","Supabase è sicuro? La piattaforma è certificata, cifrata e sottoposta a pentest. La loro documentazione dice dove finisce quello e iniziano le tue impostazioni.","2026-08-29","\u002Fblog\u002Fis-supabase-secure\u002Fcard-800x500.png",{"path":622,"title":623,"description":624,"published":625,"category":427,"image":626,"draft":431},"\u002Fblog\u002Fwhere-to-find-supabase-api-keys","Dove trovare le chiavi API di Supabase: anon, service_role e URL","L'URL del progetto, la chiave anon e la chiave service_role stanno su una pagina della dashboard. Ecco dove si trova e quale dei quattro va nella tua app.","2026-08-28","\u002Fblog\u002Fwhere-to-find-supabase-api-keys\u002Fcard-800x500.png",{"path":628,"title":629,"description":630,"published":631,"category":427,"image":632,"draft":431},"\u002Fblog\u002Fnew-row-violates-row-level-security-policy","New row violates row-level security policy su Supabase. E adesso?","\"New row violates row-level security policy\" significa che Supabase ha rifiutato una scrittura. La soluzione veloce riapre la tabella a chiunque.","2026-08-27","\u002Fblog\u002Fnew-row-violates-row-level-security-policy\u002Fcard-800x500.png",{"path":634,"title":635,"description":636,"published":637,"category":427,"image":638,"draft":431},"\u002Fblog\u002Fcors-wildcard-security-risk","Un wildcard CORS è un rischio di sicurezza? Quasi mai.","Un wildcard CORS è un rischio di sicurezza? Di solito è il valore predefinito del tuo builder e non consegna nulla che il tuo server non desse già a chiunque.","2026-08-26","\u002Fblog\u002Fcors-wildcard-security-risk\u002Fcard-800x500.png",{"path":640,"title":641,"description":642,"published":643,"category":476,"image":644,"draft":431},"\u002Fblog\u002Fsupabase-branching-is-not-a-backup","Il branching di Supabase non è un backup. Va solo in avanti.","Perché il branching di Supabase non è un backup: un branch parte senza i tuoi dati e un merge sposta solo lo schema. A cosa serve davvero e cosa usare invece.","2026-08-25","\u002Fblog\u002Fsupabase-branching-is-not-a-backup\u002Fcard-800x500.png",{"path":646,"title":647,"description":648,"published":649,"category":476,"image":650,"draft":431},"\u002Fblog\u002Fhow-to-restore-a-supabase-backup","Come ripristinare un backup Supabase, e cosa si rompe dopo","Come ripristinare un backup Supabase dalla dashboard o da un file di dump, che cosa sostituisce il ripristino e perché la tua app può restare rotta lo stesso.","2026-08-24","\u002Fblog\u002Fhow-to-restore-a-supabase-backup\u002Fcard-800x500.png",{"path":652,"title":653,"description":654,"published":655,"category":427,"image":656,"draft":431},"\u002Fblog\u002Fsupabase-storage-bucket-public","Il tuo bucket Supabase Storage è pubblico. È un problema?","Un bucket Supabase Storage pubblico significa che chi ha l'URL di un file può aprirlo. Non significa che qualcuno possa elencare quello che c'è dentro.","2026-08-23","\u002Fblog\u002Fsupabase-storage-bucket-public\u002Fcard-800x500.png",{"path":111,"title":658,"description":659,"published":660,"category":427,"image":661,"draft":431},"Una chiave API Google nel frontend è un problema?","Una chiave API Google esposta nel frontend è la chiave che il nostro scanner trova più spesso, e di solito va bene così. Lo decide una impostazione gratuita.","2026-08-22","\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":663,"title":664,"description":665,"published":666,"category":476,"image":667,"draft":431},"\u002Fblog\u002Fai-agent-deleted-my-database","Un agente IA ha cancellato i miei dati Supabase. Cosa recupero?","Un agente IA ha cancellato dati dal tuo database. Quello che puoi recuperare era già deciso prima che partisse, e i prossimi minuti decidono il resto.","2026-08-21","\u002Fblog\u002Fai-agent-deleted-my-database\u002Fcard-800x500.png",{"path":669,"title":670,"description":671,"published":672,"category":427,"image":673,"draft":431},"\u002Fblog\u002Fcan-anyone-read-your-supabase-database","Chiunque può leggere il tuo database Supabase? 3.680 app testate","Chiunque può leggere il tuo database Supabase senza fare login? Abbiamo scansionato 30.998 app online create con i builder IA e misurato quante rispondono sì.","2026-08-18","\u002Fblog\u002Fcan-anyone-read-your-supabase-database\u002Fcard-800x500.png",{"path":675,"title":676,"description":677,"published":672,"category":427,"image":678,"draft":431},"\u002Fblog\u002Fsource-maps-exposed-in-production","Source map esposte: la tua app sta pubblicando il codice originale","Una source map esposta permette a chiunque di leggere il codice originale della tua app, commenti inclusi. Il controllo da 30 secondi e cosa conta davvero.","\u002Fblog\u002Fsource-maps-exposed-in-production\u002Fcard-800x500.png",{"path":680,"title":681,"description":682,"published":683,"category":427,"image":684,"draft":431},"\u002Fblog\u002Fsupabase-new-api-keys","Le nuove chiavi API di Supabase: quale va nella tua app?","Supabase ha sostituito anon e service_role con chiavi pubblicabili e segrete. Quale sta bene nella tua app, e quale non deve starci mai?","2026-08-12","\u002Fblog\u002Fsupabase-new-api-keys\u002Fcard-800x500.png",{"path":686,"title":687,"description":688,"published":689,"category":476,"image":690,"draft":431},"\u002Fblog\u002Fdoes-supabase-back-up-my-database","Supabase fa il backup del mio database? Dipende dal tuo piano.","Supabase fa il backup del tuo database? Ogni giorno sui piani a pagamento, mai su quello gratuito. Come capire cosa hai e cosa quella copia non copre.","2026-08-11","\u002Fblog\u002Fdoes-supabase-back-up-my-database\u002Fcard-800x500.png",{"path":692,"title":693,"description":694,"published":695,"category":427,"image":696,"draft":431},"\u002Fblog\u002Fsupabase-rls-on-but-table-still-public","Supabase Row Level Security è attivo. La tabella resta pubblica.","Attivare Supabase Row Level Security non protegge una tabella. Lo fanno le policy, e quella che ha rimesso in piedi la tua app può far entrare chiunque.","2026-08-10","\u002Fblog\u002Fsupabase-rls-on-but-table-still-public\u002Fcard-800x500.png",{"path":698,"title":699,"description":700,"published":695,"category":476,"image":701,"draft":431},"\u002Fblog\u002Fversion-history-is-not-a-backup","La cronologia delle versioni non è un backup dei tuoi dati.","Lovable e Bolt tengono una cronologia delle versioni del codice. Il tuo database è un servizio a parte, e tornare indietro non ti restituisce i dati.","\u002Fblog\u002Fversion-history-is-not-a-backup\u002Fcard-800x500.png",{"path":703,"title":704,"description":705,"published":706,"category":476,"image":707,"draft":431},"\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database","Tre modi per fare il backup di un database Supabase, e cosa manca","Il pannello, pg_dump e un servizio gestito. Che cosa salva davvero ciascuno, cosa lascia fuori senza dirlo e quale sopravvive alla perdita dell'account.","2026-08-09","\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database\u002Fcard-800x500.png",{"path":406,"title":709,"description":710,"published":706,"category":427,"image":711,"draft":431},"Quali chiavi API sono sicure nel browser e quali no","La tua chiave anon di Supabase è fatta per essere pubblica. La chiave service_role no, e ignora ogni regola che imposti. Come distinguerle.","\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend\u002Fcard-800x500.png",1790150956083]