[{"data":1,"prerenderedAt":269},["ShallowReactive",2],{"research-it":3},{"id":4,"title":5,"aside":6,"body":9,"coverAlt":242,"description":243,"extension":244,"faq":245,"lede":261,"meta":262,"navigation":263,"path":264,"published":265,"seo":266,"stem":267,"updated":265,"__hash__":268},"research_it\u002Fresearch\u002Fvibe-coded-app-security-2026.md","La sicurezza delle app vibe-coded nel 2026",[7,8],"Solo uno sguardo da fuori. Leggiamo quello che il browser di un visitatore legge già: il codice che l'app spedisce, gli header che restituisce, gli indirizzi che nomina nel proprio codice. Nessun login, nessuna password indovinata, niente di scaricato.","Qui non è nominata nessuna app, né nel file dei dati. Ogni cifra porta con sé il metodo che l'ha prodotta, e il file in fondo raccoglie tutti gli aggregati in una tabella, se vuoi rifare i conti.",{"type":10,"value":11,"toc":224},"minimark",[12,17,21,24,27,31,34,37,40,44,47,50,53,56,60,63,66,70,73,76,79,82,86,89,92,95,98,102,105,108,111,125,129,132,135,138,142,214,218,221],[13,14,16],"h2",{"id":15},"sei-numeri-che-raccontano-la-storia","Sei numeri che raccontano la storia",[18,19,20],"p",{},"Queste sei cifre sono il rapporto. Tutto quello che viene dopo è la base su cui\npoggia ciascuna, e come l'abbiamo ottenuta.",[22,23],"research-key-findings",{},[18,25,26],{},"Le impostazioni predefinite delle piattaforme falliscono quasi ovunque, e la\nmaggior parte di quei fallimenti è moderata. Quello che può cambiare solo chi ha\ncostruito l'app fallisce molto più di rado, ed è quello che mette i dati di\naltre persone su internet aperta.",[13,28,30],{"id":29},"che-voto-prendono-queste-app-dalla-a-alla-f","Che voto prendono queste app, dalla A alla F",[18,32,33],{},"Reeve dà un voto a un'app come fa una pagella. Le detrazioni partono da cento e\npesano per gravità. Poi il riscontro più grave fissa un tetto: con un riscontro\ncritico l'app non va oltre la D, con uno alto non va oltre la C.",[35,36],"research-grades",{},[18,38,39],{},"La maggior parte delle app finisce in A o B. La fascia di D e F è piccola. Sono\nle app in cui uno sconosciuto può già leggere le righe di qualcun altro.",[13,41,43],{"id":42},"cosa-abbiamo-controllato-e-quante-app-hanno-fallito-ogni-controllo","Cosa abbiamo controllato, e quante app hanno fallito ogni controllo",[18,45,46],{},"Ogni controllo fa una domanda sull'app vista da fuori, ed è contato sulle app in\ncui ha ottenuto una risposta. Un'app che un controllo non è riuscito a\nraggiungere resta fuori dalla base di quel controllo, invece di essere contata\ncome pulita. Per quelle app la scansione dice che non è riuscita a controllarle,\ne questa pagina fa lo stesso.",[48,49],"research-checks-table",{},[18,51,52],{},"Due righe fanno più paura di quanta ne meritino. Gli header di sicurezza sono\nistruzioni che la piattaforma di hosting manda al browser, e se ne manca uno una\nclasse di attacchi si ritrova un ostacolo in meno davanti. Una source map\npubblicata è il codice originale dell'app posato accanto alla versione\ncompilata: mostra a un attaccante dove guardare, e da sola non consegna nulla.",[18,54,55],{},"Una riga può anche sembrare grave perché una manciata di app al suo interno ha\nspedito qualcosa di serio mentre le altre hanno spedito qualcosa di ordinario.\nIl file dei dati apre ogni riga per tipo di chiave, così si vede qual è quale.",[13,57,59],{"id":58},"più-della-metà-delle-app-supabase-controllabili-lascia-leggere-i-dati-delle-tabelle","Più della metà delle app Supabase controllabili lascia leggere i dati delle tabelle",[18,61,62],{},"È la cifra su cui siamo tornati di continuo.",[18,64,65],{},"Un progetto Supabase è aperto a internet per come è fatto. L'app che gira nel\nbrowser parla direttamente con il database, usando una chiave che deve essere\npubblica, e ciò che sta fra uno sconosciuto e le righe è Row Level Security: una\nregola su ogni tabella. Disattiva quella regola, o scrivi una policy che fa\nentrare tutti, e qualsiasi tabella del progetto si legge con una richiesta e\nsenza password.",[67,68],"research-stat",{"id":69},"supabase",[18,71,72],{},"Meno della metà delle app che nominano un progetto Supabase si riesce a\ncontrollare. Alcune mandano il traffico del database attraverso il proprio\nbackend, dove un controllo da fuori non può seguirle, quindi su quelle non\ndiciamo nulla. La quota qui sopra è calcolata sulle app che hanno risposto.",[67,74],{"id":75},"rlsSplit",[18,77,78],{},"La divisione è la parte utile. Una tabella leggibile che si chiama settings o\ncontent è un errore. Una tabella leggibile che si chiama users, profiles o\norders contiene dati personali di altre persone su internet aperta, e chi ha\ncostruito l'app quasi certamente li crede privati.",[18,80,81],{},"Il controllo non legge mai una riga. Chiede al database quante righe sarebbero\nvisibili e rilegge il conteggio da un header della risposta. Basta a distinguere\nuna tabella con una regola RLS da una senza, e il controllo non va oltre.",[13,83,85],{"id":84},"gli-stessi-nove-controlli-strumento-per-strumento","Gli stessi nove controlli, strumento per strumento",[18,87,88],{},"Ogni app è raggruppata per lo strumento con cui è stata pubblicata, e misurata\ncontro le altre app di quello strumento.",[90,91],"research-builders-table",{},[18,93,94],{},"Quasi tutto ciò che questa tabella confronta sono impostazioni predefinite.\nNessuno sceglie Lovable o Bolt per i suoi header di sicurezza. Li imposta la\npiattaforma per ogni app che ospita, quindi un solo cambiamento lì muove\nun'intera colonna di questa tabella.",[18,96,97],{},"Due limiti, prima che qualcuno citi una riga. Attribuiamo le app in base al\ndominio di pubblicazione, quindi un'app passata a un dominio personalizzato\nresta del tutto fuori da questa tabella, e spesso quelle sono le più finite. E\nuno strumento che instrada il traffico del database attraverso il proprio\nbackend non è controllabile dall'esterno per niente. Un vuoto lì vuol dire che\nnon siamo riusciti a misurare, e non dice nulla su quanto siano sicure quelle\napp.",[13,99,101],{"id":100},"due-tipi-di-riscontro-due-tipi-di-correzione","Due tipi di riscontro, due tipi di correzione",[18,103,104],{},"I riscontri di questa pagina finiscono in due gruppi, e i due hanno bisogno di\nmani diverse.",[106,107],"research-controls",{},[18,109,110],{},"Il primo gruppo è una decisione di prodotto presa in un'azienda. Una sola\nmodifica a un'impostazione predefinita dell'hosting muove in un colpo tutte le\napp di quella piattaforma, ed è per questo che quelle righe vengono fuori così\nuniformi e sono le più economiche da correggere.",[18,112,113,114,119,120,124],{},"Il secondo gruppo è nelle mani di chi ha costruito l'app. Nessuna piattaforma di\nhosting può sapere quali delle tue tabelle devono essere pubbliche, né quale\nchiave sta su un server. Ogni riscontro critico di questo rapporto è in quel\ngruppo. Le ",[115,116,118],"a",{"href":117},"\u002Fis","guide di sicurezza per strumento"," e la\n",[115,121,123],{"href":122},"\u002Fchecklist","checklist di lancio"," partono entrambe da lì.",[13,126,128],{"id":127},"cosa-fanno-bene-i-vibe-coder","Cosa fanno bene i vibe-coder",[18,130,131],{},"Abbiamo contato anche quello che passa, sulle stesse app.",[133,134],"research-clean-rates",{},[18,136,137],{},"L'ultima scheda è quella che gli scanner generici sbagliano. Una chiave\npubblicabile nel frontend (una chiave anon di Supabase, una chiave pubblicabile\ndi Stripe) è al suo posto: è fatta per essere letta, e la protezione sta nelle\nregole che le stanno dietro. Segnalarla manda qualcuno a cambiare\nun'impostazione che era già giusta.",[13,139,141],{"id":140},"come-abbiamo-misurato-e-dove-sono-i-limiti","Come abbiamo misurato, e dove sono i limiti",[143,144,145,160,175,194],"research-method",{},[146,147,149,154,157],"template",{"v-slot:origin":148},"",[150,151,153],"h3",{"id":152},"da-dove-vengono-le-app","Da dove vengono le app",[18,155,156],{},"Tre elenchi, uniti e ripuliti dai doppioni: app che la gente ha postato su X e\nReddit, app lanciate su Show HN, e app che abbiamo enumerato dai domini di\npubblicazione degli strumenti stessi. I domini di pubblicazione sono il grosso\ndel campione e l'unico elenco che scala. Gli altri due trovano solo un'app di\ncui qualcuno ha scelto di parlare.",[18,158,159],{},"Gli host morti sono usciti per primi, e lo abbiamo giudicato leggendo la pagina\nstessa. Un deploy cancellato spesso risponde ancora con un allegrissimo 200 OK.",[146,161,162,166,169,172],{"v-slot:denominator":148},[150,163,165],{"id":164},"la-regola-del-denominatore","La regola del denominatore",[18,167,168],{},"Ogni quota di questa pagina è calcolata sulle app a cui quel controllo ha potuto\nrispondere, mai sul campione intero. Un controllo che non è riuscito a\nraggiungere un'app lascia quell'app fuori dalla propria base, e non la conta mai\ncome pulita. I due numeri accanto a ogni barra sono quella base, così chiunque\nveda quale sta leggendo.",[67,170],{"id":171},"inconclusive",[18,173,174],{},"I voti sono contati su un numero più piccolo per lo stesso motivo. Un'app che ha\nrestituito troppo poco per essere classificata esce da ogni cifra qui sopra,\ninvece di essere valutata tirando a indovinare.",[146,176,177,181],{"v-slot:scope":148},[150,178,180],{"id":179},"cosa-abbiamo-fatto-e-cosa-no","Cosa abbiamo fatto, e cosa no",[182,183,184,188,191],"ul",{},[185,186,187],"li",{},"Solo letture passive: le richieste che il browser di un visitatore fa già, più\ngli indirizzi pubblici a cui l'app stessa punta.",[185,189,190],{},"Il controllo sul database prende un conteggio di righe da un header della\nrisposta. Non abbiamo mai letto una riga, scaricato un file, fatto login o\nindovinato una password.",[185,192,193],{},"Nessuna app è nominata, qui o nel file dei dati. Un elenco di app abbinate\nalle loro debolezze è un elenco di bersagli, e non ne teniamo uno in forma\npubblicabile.",[146,195,196,200],{"v-slot:limits":148},[150,197,199],{"id":198},"limiti-da-tenere-presenti","Limiti da tenere presenti",[182,201,202,205,208,211],{},[185,203,204],{},"Il campione pende verso le app più recenti. Un'app passata a un dominio\npersonalizzato non si può ricondurre a uno strumento dall'esterno, e spesso\nquelle sono le più affermate.",[185,206,207],{},"Il colore di una riga segna il caso peggiore che abbiamo visto, che può essere\nun'app su centinaia. Il file dei dati apre ogni riga per tipo esatto di chiave.",[185,209,210],{},"Questa è una finestra di tre giorni di agosto. Un'app sistemata la settimana\ndopo qui conta ancora com'era il giorno in cui l'abbiamo guardata.",[185,212,213],{},"Un controllo esterno automatico non è un audit. L'assenza di riscontri non è\nuna garanzia.",[13,215,217],{"id":216},"usate-questi-numeri","Usate questi numeri",[18,219,220],{},"Giornalisti, ricercatori e chiunque scriva di questo possono riusare i dati\ncitando la fonte. Il file qui sotto contiene tutti gli aggregati di questa\npagina in una sola tabella piatta, e non nomina nessuna app.",[222,223],"research-cite",{},{"title":148,"searchDepth":225,"depth":225,"links":226},3,[227,229,230,231,232,233,234,235,241],{"id":15,"depth":228,"text":16},2,{"id":29,"depth":228,"text":30},{"id":42,"depth":228,"text":43},{"id":58,"depth":228,"text":59},{"id":84,"depth":228,"text":85},{"id":100,"depth":228,"text":101},{"id":127,"depth":228,"text":128},{"id":140,"depth":228,"text":141,"children":236},[237,238,239,240],{"id":152,"depth":225,"text":153},{"id":164,"depth":225,"text":165},{"id":179,"depth":225,"text":180},{"id":198,"depth":225,"text":199},{"id":216,"depth":228,"text":217},"Una card scura con il marchio Reeve, il titolo del rapporto e il numero di app online della scansione scritto in cifre grandi.","Abbiamo fatto gli stessi nove controlli esterni su decine di migliaia di app online create con Lovable, Bolt, v0, Replit e Base44. Ecco il risultato.","md",[246,249,252,255,258],{"q":247,"a":248},"Potete dirmi quali app avevano quali problemi?","No. Solo conteggi e quote, mai nomi, e il file dei dati contiene esattamente quello che la pagina mostra. Un elenco di app abbinate alle loro debolezze è un elenco di bersagli, e non lo produrremo.",{"q":250,"a":251},"La mia app potrebbe essere in questi dati. Cosa faccio?","Scansionala tu. Sono gli stessi nove controlli, richiedono una ventina di secondi e ti danno il voto insieme a quello che uno sconosciuto vede già. Niente in questa pagina identifica nessuno, quindi è l'unico modo per sapere a che punto sei.",{"q":253,"a":254},"Una tabella del database leggibile è davvero così grave?","Se chiunque su internet può tirare fuori quelle righe con una richiesta e senza password, sì. Una tabella leggibile che si chiama settings è sciatteria. Una tabella leggibile che si chiama users o orders è una fuga di dati che ancora nessuno ha notato.",{"q":256,"a":257},"Perché considerate normali le chiavi pubblicabili?","La chiave anon di Supabase deve essere pubblica. La protezione sta nelle regole del database dietro di lei, non nella chiave stessa. Gli strumenti che segnalano quelle chiavi insegnano alla gente a saltare l'avviso successivo, che magari è quello che conta.",{"q":259,"a":260},"Rifarete questa analisi?","Sì. Le scansioni continuano e la prossima edizione arriva da lì. Il file dei dati registra la finestra da cui vengono queste cifre, così una copia vecchia non passa per attuale.","Abbiamo cercato app online costruite con Lovable, Bolt, v0, Replit o Base44, poi le abbiamo passate tutte agli stessi nove controlli che chiunque può fare gratis dalla home page di Reeve. Questa pagina è quello che ne è venuto fuori.",{},true,"\u002Fresearch\u002Fvibe-coded-app-security-2026","2026-08-19",{"title":5,"description":243},"research\u002Fvibe-coded-app-security-2026","EyrNR2BDg4vx7FpIcgIb_Nin_4GvIA-Z2jrJVbEMI0U",1787826050977]