[{"data":1,"prerenderedAt":999},["ShallowReactive",2],{"blog-es-env-file-exposed-on-your-server":3,"blog-index-es":646},{"id":4,"title":5,"body":6,"category":601,"cover":602,"coverAlt":603,"description":604,"draft":605,"extension":606,"faq":607,"image":623,"keywords":624,"meta":633,"navigation":634,"ogTitle":635,"path":636,"published":637,"seo":638,"stem":639,"tldr":640,"updated":644,"__hash__":645},"blog_es\u002Fblog\u002Fenv-file-exposed-on-your-server.md","¿Tu archivo .env está expuesto? Las doce rutas a revisar",{"type":7,"value":8,"toc":587},"minimark",[9,18,36,42,47,54,57,63,69,83,100,104,107,166,175,181,185,188,197,200,207,214,218,221,392,399,403,406,409,435,443,447,453,459,468,475,479,489,492,505,509,512,515,520,523,545,552,556,579],[10,11,12,13,17],"p",{},"Alguien te ha dicho que tu archivo ",[14,15,16],"code",{},".env"," está expuesto, y por la frase no puedes\nsaber si eso es grave. Cubre dos situaciones completamente distintas. Una de\nellas es la herramienta funcionando como debe. La otra significa que un archivo\nque creías privado se puede descargar desde tu sitio en vivo, por cualquiera,\ndesde el día en que está ahí.",[10,19,20,21,31,32,35],{},"Esta es la parte que guía tras guía mezcla: ",[22,23,24,25,27,28,30],"strong",{},"que un valor de tu ",[14,26,16],{}," acabe\ndentro de tu JavaScript no es el mismo suceso que tu servidor web sirviendo el\narchivo ",[14,29,16],{},"."," Lo primero es el build haciendo lo que le pediste cuando\nllamaste a la variable ",[14,33,34],{},"VITE_ALGO",". Lo segundo es un error de archivo, y es lo\nque conviene mirar antes, porque puedes comprobarlo tú desde fuera en un minuto.",[10,37,38,39,41],{},"Piensa en tu sitio en vivo como el mostrador de una tienda. Todo lo que hay en el\nmostrador está para llevarse: la página, las imágenes, el JavaScript, el\nlogotipo. La trastienda guarda lo que hace funcionar el negocio, y un visitante\nno tiene camino hasta ahí. Un valor compilado dentro de tu JavaScript es una\nlínea impresa en el folleto del mostrador. El archivo ",[14,40,16],{}," que responde en una\ndirección pública es la carpeta de la trastienda, dejada en el mostrador junto a\ntodo lo demás.",[43,44,46],"h2",{"id":45},"mi-archivo-env-está-expuesto","¿Mi archivo .env está expuesto?",[10,48,49,50,53],{},"Abre tu sitio en vivo en un navegador, añade ",[14,51,52],{},"\u002F.env"," al final de la dirección y\npulsa enter.",[10,55,56],{},"Pueden volver tres cosas, y solo una de ellas es un problema.",[10,58,59,62],{},[22,60,61],{},"Una página de tu aplicación."," La mayoría de los frontends responden a\ncualquier dirección desconocida con su propia página índice, porque así enruta\nuna aplicación de una sola página. Te sale tu portada, o tu pantalla de no\nencontrado. En esa ruta no se sirve nada.",[10,64,65,68],{},[22,66,67],{},"Un error."," Un 403 o un 404 significa que al servidor se le preguntó y\ndeclinó. Esa es la respuesta que quieres.",[10,70,71,74,75,78,79,82],{},[22,72,73],{},"Texto plano, con líneas dentro."," Algo como ",[14,76,77],{},"SUPABASE_URL=https:\u002F\u002F…"," y\n",[14,80,81],{},"SUPABASE_SERVICE_ROLE_KEY=eyJ…",", en un muro monoespaciado sin estilo alguno. El\narchivo se entrega a quien lo pida, y lleva haciéndolo desde el día en que se\nsirvió por primera vez.",[84,85,87],"callout",{"type":86},"note",[10,88,89,92,93,96,97,99],{},[22,90,91],{},"Mira lo que volvió, no el código de estado."," Un servidor puede responder\n",[14,94,95],{},"200 OK"," con tu página índice, que es el resultado normal y no significa nada\nmalo. Los navegadores además dibujan un ",[14,98,16],{}," descargado como texto desnudo,\nasí que la ventana parece rota justo cuando el hallazgo es real. La prueba es si\nestás leyendo tus propios ajustes.",[43,101,103],{"id":102},"dos-cosas-distintas-se-llaman-archivo-env-expuesto","Dos cosas distintas se llaman archivo .env expuesto",[10,105,106],{},"Una va de tu bundle. La otra va de tu servidor.",[108,109,110,126],"table",{},[111,112,113],"thead",{},[114,115,116,120,123],"tr",{},[117,118,119],"th",{},"Qué ha pasado",[117,121,122],{},"Dónde está el valor",[117,124,125],{},"Qué cuesta arreglarlo",[127,128,129,152],"tbody",{},[114,130,131,146,149],{},[132,133,134,135,138,139,142,143],"td",{},"Llamaste a una variable ",[14,136,137],{},"VITE_",", ",[14,140,141],{},"NEXT_PUBLIC_"," o ",[14,144,145],{},"EXPO_PUBLIC_",[132,147,148],{},"Compilado en el JavaScript que descarga cada visitante",[132,150,151],{},"Mover el trabajo a un servidor y rotar la clave. El archivo nunca se sirvió.",[114,153,154,157,163],{},[132,155,156],{},"Tu servidor web publica tu carpeta de proyecto",[132,158,159,160],{},"En el archivo, en ",[14,161,162],{},"https:\u002F\u002Ftusitio\u002F.env",[132,164,165],{},"Sacar el archivo de lo que publica el servidor y rotar todo lo que contenía.",[10,167,168,169,174],{},"La primera fila es la común y tiene ",[170,171,173],"a",{"href":172},"\u002Fblog\u002Fvite-and-next-public-env-vars","su propio\nartículo",": el prefijo es una instrucción de\npublicar, y el build la obedeció. Todo lo de abajo es la segunda fila.",[176,177],"diagram",{"alt":178,"caption":179,"src":180},"Dos rutas de salida del mismo archivo .env. A la izquierda el build copia un valor con prefijo al bundle de JavaScript que descarga un visitante. A la derecha el servidor web entrega el archivo entero en la dirección \u002F.env.","Izquierda: el build copió un valor a tu JavaScript, porque el prefijo se lo pidió. Derecha: el servidor entrega el archivo, y los prefijos ahí no cambian nada.","\u002Fblog\u002Fenv-file-exposed-on-your-server\u002Ftwo-meanings-1600x840.png",[43,182,184],{"id":183},"por-qué-una-aplicación-de-lovable-no-puede-y-una-de-replit-sí","Por qué una aplicación de Lovable no puede y una de Replit sí",[10,186,187],{},"Porque los dos hosts publican cosas distintas.",[10,189,190,191,193,194,196],{},"Un builder que despliega un frontend estático le entrega a su host una carpeta de\narchivos construidos: algo de HTML, algo de JavaScript, algunas imágenes. Tu\n",[14,192,16],{}," se leyó durante el build y no está en esa carpeta, así que en ",[14,195,52],{}," no\nhay nada que nadie pueda pedir. El host no podría servir el archivo ni\nqueriendo.",[10,198,199],{},"Una aplicación de Replit suele ejecutar su propio servidor, en su propia carpeta\nde proyecto, con tus archivos al lado de tu código. A un servidor al que se le\ndice que sirva su carpeta sirve todos los archivos que hay en ella, y no tiene\nmanera de saber que uno de ellos guarda tus claves. Lo mismo vale para cualquier\ncosa que hayas desplegado en una máquina tuya.",[10,201,202,203,206],{},"Los números siguen a la arquitectura. De 30.761 aplicaciones en vivo donde esta\ncomprobación obtuvo respuesta, 8 entregaban al menos un archivo privado. ",[22,204,205],{},"Siete\nde las ocho eran de Replit",", y las de Replit eran 3.025 de las 30.761. La octava\nestaba en un dominio propio, que dice lo mismo de otra manera: alguien tenía su\npropio servidor.",[10,208,209,210,30],{},"Es el hallazgo más raro que imprimimos, y el único de los nueve sin explicación\ninocente. Si quieres la lectura amplia de lo que entregan de verdad las\naplicaciones de Replit, ",[170,211,213],{"href":212},"\u002Fblog\u002Fis-replit-safe","escaneamos 3.042 de ellas",[43,215,217],{"id":216},"las-doce-rutas-a-revisar","Las doce rutas a revisar",[10,219,220],{},"Doce direcciones, en el orden que merece la pena. Pon cada una detrás de tu\ndominio.",[108,222,223,236],{},[111,224,225],{},[114,226,227,230,233],{},[117,228,229],{},"Dirección",[117,231,232],{},"Qué guarda",[117,234,235],{},"Si responde con texto",[127,237,238,250,263,275,292,305,318,331,342,353,366,379],{},[114,239,240,244,247],{},[132,241,242],{},[14,243,52],{},[132,245,246],{},"Todas las claves con las que se construyó tu app",[132,248,249],{},"Trátalo todo como público y rota",[114,251,252,257,260],{},[132,253,254],{},[14,255,256],{},"\u002F.env.local",[132,258,259],{},"Lo mismo, de una ejecución local",[132,261,262],{},"Lo mismo",[114,264,265,270,273],{},[132,266,267],{},[14,268,269],{},"\u002F.env.production",[132,271,272],{},"Lo mismo, de tu despliegue en vivo",[132,274,262],{},[114,276,277,282,285],{},[132,278,279],{},[14,280,281],{},"\u002F.git\u002Fconfig",[132,283,284],{},"La dirección remota de tu repositorio",[132,286,287,288,291],{},"Todo el directorio ",[14,289,290],{},".git"," suele ser legible",[114,293,294,299,302],{},[132,295,296],{},[14,297,298],{},"\u002F.git\u002FHEAD",[132,300,301],{},"En qué rama estás",[132,303,304],{},"Lo mismo, y es la más silenciosa de las doce",[114,306,307,312,315],{},[132,308,309],{},[14,310,311],{},"\u002F.aws\u002Fcredentials",[132,313,314],{},"Claves de Amazon de larga duración",[132,316,317],{},"Rota en Amazon y luego revisa la factura",[114,319,320,325,328],{},[132,321,322],{},[14,323,324],{},"\u002Fdatabase.sql",[132,326,327],{},"Esquema y filas",[132,329,330],{},"Todas las filas de todas las tablas son públicas",[114,332,333,338,340],{},[132,334,335],{},[14,336,337],{},"\u002Fdump.sql",[132,339,262],{},[132,341,262],{},[114,343,344,349,351],{},[132,345,346],{},[14,347,348],{},"\u002Fbackup.sql",[132,350,262],{},[132,352,262],{},[114,354,355,360,363],{},[132,356,357],{},[14,358,359],{},"\u002Fconfig.json",[132,361,362],{},"Lo que hayas puesto dentro",[132,364,365],{},"Léelo y mira; hay tokens ahí más a menudo de lo que se cree",[114,367,368,373,376],{},[132,369,370],{},[14,371,372],{},"\u002Fdocker-compose.yml",[132,374,375],{},"Definiciones de servicios, a menudo con contraseñas",[132,377,378],{},"Rota todo lo que esté escrito dentro",[114,380,381,386,389],{},[132,382,383],{},[14,384,385],{},"\u002F.npmrc",[132,387,388],{},"Un token de registro",[132,390,391],{},"Revoca el token",[10,393,394,395,30],{},"Nuestro propio escaneo lee las doce desde fuera y te nombra las que\nrespondieron. Tarda unos 20 segundos y no necesita cuenta: ",[170,396,398],{"href":397},"\u002Fsecurity-scanner","escanea tu\naplicación",[43,400,402],{"id":401},"qué-significa-de-verdad-un-acierto","Qué significa de verdad un acierto",[10,404,405],{},"Todo lo que hay en ese archivo es público ahora mismo, y lo es desde el día en\nque se sirvió por primera vez.",[10,407,408],{},"No vas a averiguar quién lo leyó. Un builder no te da un registro de archivos\ndescargados que puedas ir a mirar, y la petición se ve igual que cualquier otra\npetición de cualquier otro archivo. De lo que sí puedes estar seguro es de que\nalguien lo intentó: hay crawlers automáticos recorriendo exactamente estas doce\nrutas por todo internet, sin parar, y no necesitan saber quién eres para dar con\nla tuya.",[10,410,411,412,414,415,138,417,420,421,424,425,138,428,142,431,434],{},"Cinco de las ocho aplicaciones que encontramos entregaban una de las cuatro caras\nde inmediato: ",[14,413,16],{},", un directorio ",[14,416,290],{},[14,418,419],{},".aws\u002Fcredentials"," o un dump ",[14,422,423],{},".sql",".\nLas otras tres entregaban ",[14,426,427],{},"config.json",[14,429,430],{},"docker-compose.yml",[14,432,433],{},".npmrc",". Esas\ntres son las que todo el mundo da por inofensivas, que es justo por lo que acaban\ncon tokens y contraseñas de base de datos escritos dentro.",[10,436,437,438,442],{},"Lo que esto no es, es un veredicto sobre tu aplicación. Una comprobación externa\nlee lo que tu sitio le entrega a un desconocido, y doce rutas que responden con\nnada son doce rutas que responden con nada. ",[170,439,441],{"href":440},"\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps","Qué más se escapa de una aplicación\nvibe-codeada"," es la lista larga.",[43,444,446],{"id":445},"la-que-arruina-una-semana-un-directorio-git","La que arruina una semana: un directorio .git",[10,448,449,450,452],{},"Un directorio ",[14,451,290],{}," no es un archivo. Es todo tu historial.",[10,454,455,456,458],{},"Ahí está cada commit, incluido aquel en el que pegaste una clave y el posterior\nen el que la quitaste. Esa es la parte que la gente entiende mal de una fuga de\n",[14,457,290],{},": borrar un secreto del código que tienes hoy no hace nada con la versión\ndonde seguía estando, y esa versión está en el mismo directorio que tu servidor\npublica.",[10,460,461,462,464,465,467],{},"La comprobación lee ",[14,463,281],{}," y ",[14,466,298],{}," porque son pequeños, su\ncontenido es inconfundible y cualquiera de los dos respondiendo significa que el\ndirectorio en sí se está sirviendo. A partir de ahí quien lee no necesita ninguna\nherramienta especial. El formato está documentado y software corriente lo clona.",[10,469,470,471,30],{},"Si una clave estuvo alguna vez en un commit, rotarla es lo único que ayuda. Cuál\nva primero depende de si la copia ya está fuera, y ",[170,472,474],{"href":473},"\u002Fblog\u002Frotate-supabase-service-role-key","ese orden merece la pena\nacertarlo",[43,476,478],{"id":477},"el-dump-que-alguien-dejó-en-la-carpeta","El dump que alguien dejó en la carpeta",[10,480,481,482,484,485,464,487,30],{},"Tres de las doce rutas son volcados de base de datos: ",[14,483,324],{},",\n",[14,486,337],{},[14,488,348],{},[10,490,491],{},"Un dump son todas las filas de todas las tablas en un archivo, con el esquema\nencima. Direcciones de correo, contraseñas con hash, pedidos, mensajes, lo que\nguarde tu aplicación. Responde en una dirección pública por el motivo más\naburrido de todo este artículo: alguien hizo lo responsable, sacó una copia de su\nbase de datos y la guardó en la carpeta de proyecto donde estaba.",[10,493,494,495,499,500,504],{},"Así que el archivo hecho para proteger los datos se convirtió en la vía más\nrápida de leerlos todos. Dónde vive una copia es tanta decisión como si la haces.\n",[170,496,498],{"href":497},"\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database","Tres formas de respaldar una base de datos\nSupabase"," repasa las opciones, y\n",[170,501,503],{"href":502},"\u002Fsupabase-backups","Reeve Care"," guarda una copia de tu base de datos de Supabase\nfuera de tu propio servidor, verificada antes de contar como copia.",[43,506,508],{"id":507},"cómo-arreglarlo-y-por-qué-importa-el-orden","Cómo arreglarlo, y por qué importa el orden",[10,510,511],{},"Saca el archivo de lo que publica tu servidor. Después rota cada secreto que\ntenía dentro. En ese orden.",[10,513,514],{},"Rotar primero parece la mitad urgente, y es la mitad que desperdicia el trabajo.\nTus claves nuevas van al mismo archivo, el archivo sigue respondiendo en la misma\ndirección, y has rotado directamente de vuelta a la fuga. Nada está más seguro\nque hace diez minutos.",[176,516],{"alt":517,"caption":518,"src":519},"Dos secuencias. Rotar antes de mover el archivo devuelve la clave nueva al archivo que el servidor sigue sirviendo. Mover el archivo primero deja la clave rotada en un sitio al que nadie llega.","Rota primero y la clave nueva aterriza en el archivo que se sigue entregando. Mueve primero y ya no queda nada que entregar.","\u002Fblog\u002Fenv-file-exposed-on-your-server\u002Ffix-order-1600x760.png",[10,521,522],{},"Dónde ponerlo en su lugar, según lo que tengas montado:",[524,525,526,533,539],"ul",{},[527,528,529,532],"li",{},[22,530,531],{},"Un host con su propio almacén de secretos."," Replit Secrets, las variables de\nentorno de una plataforma, tu panel de hosting. Tu servidor lee el valor en\ntiempo de ejecución y nunca queda en un archivo dentro de la carpeta publicada.",[527,534,535,538],{},[22,536,537],{},"Fuera de la carpeta servida."," Si controlas la configuración del servidor,\napúntalo a una carpeta de salida del build en lugar de a la raíz del proyecto.\nEntonces un archivo en la raíz no tiene dirección ninguna.",[527,540,541,544],{},[22,542,543],{},"Tampoco en el repositorio",", que es una costumbre aparte y buena. Con el\nproblema de hoy no hace nada.",[10,546,547,548,551],{},"Ese último punto conviene decirlo claro, porque ",[14,549,550],{},".gitignore"," es la respuesta a la\nque todo el mundo va. Mantiene el archivo fuera de tu repositorio. El archivo de\ntu servidor llegó ahí porque el servidor está sentado en tu carpeta de proyecto,\ny git no tiene opinión sobre eso.",[43,553,555],{"id":554},"qué-hacer-ahora-mismo","Qué hacer ahora mismo",[557,558,559],"key-takeaways",{},[524,560,561,564,567,570,573],{},[527,562,563],{},"Escribe las doce direcciones detrás de tu propio dominio, o lanza el escaneo gratuito y que escriba él. Lee lo que vuelve, no el código de estado.",[527,565,566],{},"Si una responde con tus propios ajustes, saca el archivo de la carpeta que publica tu servidor y vuelve a desplegar. Ese es el paso que lo corta.",[527,568,569],{},"Después rota cada clave, contraseña y token que tenía el archivo, en cada proveedor. Rotar antes de mover el archivo devuelve los valores nuevos a donde estaban los viejos.",[527,571,572],{},"Revisa facturación y registros del proveedor al terminar. Rotar corta lo que viene después y no hace nada con lo que ya pasó.",[527,574,575,576,578],{},"Si un directorio ",[14,577,290],{}," era legible, rota todo lo que estuvo alguna vez en un commit, no solo lo que hay hoy en el código.",[10,580,581,582,586],{},"Si prefieres recorrer tu aplicación como una lista, la ",[170,583,585],{"href":584},"\u002Fchecklist","checklist de seguridad de\n10 minutos"," cubre esto junto a las otras cosas que conviene cerrar en\nuna aplicación recién lanzada.",{"title":588,"searchDepth":589,"depth":589,"links":590},"",3,[591,593,594,595,596,597,598,599,600],{"id":45,"depth":592,"text":46},2,{"id":102,"depth":592,"text":103},{"id":183,"depth":592,"text":184},{"id":216,"depth":592,"text":217},{"id":401,"depth":592,"text":402},{"id":445,"depth":592,"text":446},{"id":477,"depth":592,"text":478},{"id":507,"depth":592,"text":508},{"id":554,"depth":592,"text":555},"Fundamentos de seguridad","\u002Fblog\u002Fenv-file-exposed-on-your-server\u002Fcover-1200x630.png","Cuatro carpetas selladas detrás de un muro y, delante, una carpeta abierta con sus líneas a la vista bajo una franja ámbar.","¿Tu archivo .env está expuesto en tu propio servidor web? Doce direcciones te lo dicen, y un acierto significa que todo lo que contiene ya es público.",false,"md",[608,611,614,617,620],{"q":609,"a":610},"¿Cómo sé si mi archivo .env es público?","Abre tu sitio en vivo en un navegador, añade \u002F.env al final de la dirección y pulsa enter. Si vuelve una página de tu aplicación, no se está sirviendo nada en esa ruta. Si vuelve texto plano, con líneas como SUPABASE_URL=https:\u002F\u002Fabcdefghij.supabase.co, el archivo se entrega a quien lo pida. Haz lo mismo con \u002F.env.local y \u002F.env.production, porque un servidor que publica uno suele publicar los tres.",{"q":612,"a":613},"¿Un archivo .env en mi bundle es lo mismo?","No, y la solución es otra. Un valor que acaba dentro de tu JavaScript llegó ahí porque al build se le pidió, con una variable llamada VITE_ o NEXT_PUBLIC_ o EXPO_PUBLIC_. El archivo nunca salió de tu máquina; el valor sí. Ese es un problema aparte y tiene su propio artículo. Este va del archivo en sí, servido por tu servidor web, lo que deja público cada valor que contiene, lleve prefijo o no.",{"q":615,"a":616},"¿Por qué alguien puede descargar mi carpeta .git?","Porque tu servidor apunta a tu carpeta de proyecto y .git es un directorio dentro de ella como cualquier otro. Un servidor no sabe que uno de ellos es tu historial de versiones. Si \u002F.git\u002Fconfig o \u002F.git\u002FHEAD responde con texto, todo el directorio suele ser legible, y eso incluye cada commit que hiciste, no solo el código que tienes hoy.",{"q":618,"a":619},"He encontrado un backup.sql en mi propio sitio, ¿y ahora?","Sácalo de la carpeta que publica tu servidor antes de hacer nada más, porque el archivo se está entregando mientras lees esto. Después trata como público cada contraseña, clave y dato personal que contenga: un dump lleva el esquema y todas las filas de todas las tablas. Y averigua cómo llegó ahí, que suele ser alguien que hizo una copia en la carpeta del proyecto y nunca la movió.",{"q":621,"a":622},"¿Roto las claves o borro el archivo primero?","Mueve el archivo primero y rota después. Rotar mientras el archivo se sigue sirviendo escribe los valores nuevos en algo que cualquiera puede descargar, así que gastas el trabajo y acabas donde estabas. Cuando ya no responda nada en esa ruta, rota cada secreto que tenía el archivo, en cada proveedor, y revisa facturación y registros al terminar.","\u002Fblog\u002Fenv-file-exposed-on-your-server\u002Fcard-800x500.png",[625,626,627,628,629,630,631,632],"archivo .env expuesto","archivo env accesible públicamente",".env expuesto en el servidor","descargar .env de una web","carpeta .git expuesta","mi archivo .env es público","backup.sql expuesto","config.json expuesto",{},true,"¿Tu archivo .env está expuesto? Doce rutas a revisar","\u002Fblog\u002Fenv-file-exposed-on-your-server","2026-10-04",{"title":5,"description":604},"blog\u002Fenv-file-exposed-on-your-server",[641,642,643],"Dos problemas distintos se llaman igual: un archivo .env expuesto. Este es el archivo en sí, puesto en tu servidor web y descargable por cualquiera que escriba la dirección.","Un host que solo sirve tu frontend ya construido no puede hacer esto. Un servidor de verdad sí, y por eso siete de las ocho aplicaciones que encontramos eran de Replit.","De 30.761 aplicaciones en vivo donde nuestra comprobación obtuvo respuesta, 8 estaban entregando un archivo privado. Doce direcciones te dicen si eres la novena.","2026-10-05","0zPqCsJOOb5s4ZVjuHH6f0n553o_IVKEj0i_iPBi3cQ",[647,653,659,665,671,677,683,688,689,695,701,707,713,719,726,732,738,743,749,755,761,767,773,779,785,790,796,802,807,813,819,825,831,837,843,848,854,860,866,872,878,883,889,895,901,907,913,919,925,931,937,943,949,955,961,966,972,978,984,989,994],{"path":648,"title":649,"description":650,"published":651,"category":601,"image":652,"draft":605},"\u002Fblog\u002Fstorage-upload-violates-row-level-security","\"Row-level security policy for table objects\" al subir","\"New row violates row-level security policy for table objects\" significa que tu subida no tiene regla insert. Hacer público el bucket no añade ninguna.","2026-10-11","\u002Fblog\u002Fstorage-upload-violates-row-level-security\u002Fcard-800x500.png",{"path":654,"title":655,"description":656,"published":657,"category":601,"image":658,"draft":605},"\u002Fblog\u002Fbase44-security-scan","Escaneo de seguridad de Base44: lo que solo él ve","El escaneo de seguridad de Base44 revisa siete tipos de problema desde dentro. Esta es la mitad que lee y nadie más puede leer, y la mitad que nunca mira.","2026-10-10","\u002Fblog\u002Fbase44-security-scan\u002Fcard-800x500.png",{"path":660,"title":661,"description":662,"published":663,"category":601,"image":664,"draft":605},"\u002Fblog\u002Fapi-key-leaked-what-to-do","Tu clave API se filtró. El orden en el que hay que actuar","Una clave API se filtró y no sabes por dónde empezar. No todas las claves de tu frontend lo son, y el orden importa más que la velocidad.","2026-10-09","\u002Fblog\u002Fapi-key-leaked-what-to-do\u002Fcard-800x500.png",{"path":666,"title":667,"description":668,"published":669,"category":601,"image":670,"draft":605},"\u002Fblog\u002Finfinite-recursion-in-policy-for-relation","\"Infinite recursion detected in policy\" sin desactivar RLS","\"Infinite recursion detected in policy for relation\" significa que tu policy preguntó a la tabla que protege. Así se rompe el círculo.","2026-10-08","\u002Fblog\u002Finfinite-recursion-in-policy-for-relation\u002Fcard-800x500.png",{"path":672,"title":673,"description":674,"published":675,"category":601,"image":676,"draft":605},"\u002Fblog\u002Fno-api-key-found-in-request","\"No API key found in request\" en Supabase, y el arreglo equivocado","\"No API key found in request\" significa que tu petición llegó a Supabase sin clave. Casi todas las respuestas apuntan a las reglas de tu base de datos.","2026-10-07","\u002Fblog\u002Fno-api-key-found-in-request\u002Fcard-800x500.png",{"path":678,"title":679,"description":680,"published":681,"category":601,"image":682,"draft":605},"\u002Fblog\u002Fis-base44-safe","¿Es seguro Base44? Lo que vimos en 5.442 apps Base44","¿Es seguro Base44? Pasamos nueve comprobaciones a 5.442 apps Base44 en producción. Casi todas sacaron B por motivos que su dueño nunca eligió.","2026-10-06","\u002Fblog\u002Fis-base44-safe\u002Fcard-800x500.png",{"path":684,"title":685,"description":686,"published":644,"category":601,"image":687,"draft":605},"\u002Fblog\u002Fmove-a-secret-to-an-edge-function","Ocultar una clave API: muévela a una Edge Function de Supabase","Ocultar una clave API significa sacarla del navegador, y una Edge Function de Supabase es el sitio más pequeño donde ponerla. Dos pasos importan más.","\u002Fblog\u002Fmove-a-secret-to-an-edge-function\u002Fcard-800x500.png",{"path":636,"title":5,"description":604,"published":637,"category":601,"image":623,"draft":605},{"path":690,"title":691,"description":692,"published":693,"category":601,"image":694,"draft":605},"\u002Fblog\u002Fis-v0-safe","Seguridad de v0: las 1.790 aplicaciones escaneadas sacaron una A","Seguridad de v0, medida en 1.790 aplicaciones v0 en vivo: todas sacaron A. Solo 17 nombraban una base de datos, y eso es casi todo lo que mide la A.","2026-10-03","\u002Fblog\u002Fis-v0-safe\u002Fcard-800x500.png",{"path":696,"title":697,"description":698,"published":699,"category":601,"image":700,"draft":605},"\u002Fblog\u002Fis-bolt-safe","¿Es seguro Bolt? Lo que vimos en 1.123 aplicaciones Bolt","¿Es seguro Bolt? Pasamos 1.123 aplicaciones Bolt en vivo por nueve comprobaciones. El hosting salió limpio. Los hallazgos eran claves y tablas abiertas dentro.","2026-10-02","\u002Fblog\u002Fis-bolt-safe\u002Fcard-800x500.png",{"path":702,"title":703,"description":704,"published":705,"category":601,"image":706,"draft":605},"\u002Fblog\u002Fis-supabase-down-or-your-app","¿Supabase está caído o es tu app? Cómo distinguirlo","¿Supabase está caído o es tu app? Un proyecto pausado, una base de datos llena y un fallo tuyo parecen lo mismo. Cuatro comprobaciones los separan.","2026-10-01","\u002Fblog\u002Fis-supabase-down-or-your-app\u002Fcard-800x500.png",{"path":708,"title":709,"description":710,"published":711,"category":601,"image":712,"draft":605},"\u002Fblog\u002Fdoes-supabase-encrypt-my-data","¿Supabase cifra mis datos? Sí. Esto es lo que detiene","¿Supabase cifra los datos? Sí: AES-256 en reposo, TLS en tránsito, SOC 2 e ISO 27001. Qué cubre cada uno, y la fuga que ninguno de ellos detiene.","2026-09-30","\u002Fblog\u002Fdoes-supabase-encrypt-my-data\u002Fcard-800x500.png",{"path":714,"title":715,"description":716,"published":717,"category":601,"image":718,"draft":605},"\u002Fblog\u002Fsupabase-free-plan-limits","¿Cuánto cuesta Supabase? Los límites del plan gratuito","Los límites del plan gratuito de Supabase: 500 MB de base de datos, 5 GB de egress y ningún backup. Qué pasa en cada uno y qué cambia Pro por $25.","2026-09-29","\u002Fblog\u002Fsupabase-free-plan-limits\u002Fcard-800x500.png",{"path":720,"title":721,"description":722,"published":723,"category":724,"image":725,"draft":605},"\u002Fblog\u002Ftest-your-supabase-backup","Prueba tu backup de Supabase antes del día que lo necesites","Cómo probar tu backup de Supabase: restaurarlo en un proyecto de prueba, contar filas, iniciar sesión y buscar la línea que le falta a un archivo cortado.","2026-09-28","Backups","\u002Fblog\u002Ftest-your-supabase-backup\u002Fcard-800x500.png",{"path":727,"title":728,"description":729,"published":730,"category":724,"image":731,"draft":605},"\u002Fblog\u002Fsupabase-backup-github-action","Backup gratis de Supabase con una GitHub Action, y la trampa","Un backup de Supabase con GitHub Action es gratis y sirve a muchas apps. El workflow, el connection string correcto y el egress de cada ejecución.","2026-09-27","\u002Fblog\u002Fsupabase-backup-github-action\u002Fcard-800x500.png",{"path":733,"title":734,"description":735,"published":736,"category":724,"image":737,"draft":605},"\u002Fblog\u002Fdownload-your-supabase-backup","Por qué no puedes descargar tu backup de Supabase","No puedes descargar tu backup de Supabase en un proyecto actual: la copia diaria es una instantánea física. Cómo comprobarlo y tener tu propia copia.","2026-09-26","\u002Fblog\u002Fdownload-your-supabase-backup\u002Fcard-800x500.png",{"path":739,"title":740,"description":741,"published":736,"category":601,"image":742,"draft":605},"\u002Fblog\u002Fsupabase-permission-denied-for-table","Supabase \"permission denied for table\": el grant que falta","Desde el 30 de octubre, una tabla nueva de Supabase responde \"permission denied for table\" hasta que le das acceso. El grant del email es la mitad del arreglo.","\u002Fblog\u002Fsupabase-permission-denied-for-table\u002Fcard-800x500.png",{"path":744,"title":745,"description":746,"published":747,"category":601,"image":748,"draft":605},"\u002Fblog\u002Fopen-api-endpoint-exposed","¿Un endpoint de API abierto es un problema? Mira el JSON","Tu escaneo señaló un endpoint de API abierto. Que importe depende de lo que devolvió, y la mayoría de los que encontramos eran de la plataforma.","2026-09-25","\u002Fblog\u002Fopen-api-endpoint-exposed\u002Fcard-800x500.png",{"path":750,"title":751,"description":752,"published":753,"category":601,"image":754,"draft":605},"\u002Fblog\u002Flovable-security-scan","Escaneo de seguridad de Lovable: lo que no puede probar","Escaneo de seguridad de Lovable: qué revisan el Quick scan y el Deep scan, cuándo corre cada uno, y lo único que ningún escaneo desde dentro puede probar.","2026-09-24","\u002Fblog\u002Flovable-security-scan\u002Fcard-800x500.png",{"path":756,"title":757,"description":758,"published":759,"category":724,"image":760,"draft":605},"\u002Fblog\u002Fsupabase-backup-auth-users","Por qué tu dump de Supabase no tiene usuarios dentro","Ejecuta supabase db dump por sí solo y obtienes la forma de tu base de datos y ninguna de sus filas, sin el esquema auth donde viven tus usuarios.","2026-09-23","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",{"path":762,"title":763,"description":764,"published":765,"category":601,"image":766,"draft":605},"\u002Fblog\u002Fdomain-and-certificate-expiry","Dominio caducado, web caída: qué pasa a partir de ahora","Tu dominio caducó y tu web está caída. Aquí tienes el reloj que acaba de arrancar, por qué el certificado es el menor problema, y cómo comprobar ambos.","2026-09-22","\u002Fblog\u002Fdomain-and-certificate-expiry\u002Fcard-800x500.png",{"path":768,"title":769,"description":770,"published":771,"category":601,"image":772,"draft":605},"\u002Fblog\u002Fis-lovable-safe","¿Es seguro Lovable? Lo que vimos en 18.554 aplicaciones Lovable","¿Es seguro Lovable? Pasamos 18.554 aplicaciones Lovable por nueve comprobaciones. La plataforma fue la más limpia de cinco. Los hallazgos estaban dentro.","2026-09-21","\u002Fblog\u002Fis-lovable-safe\u002Fcard-800x500.png",{"path":774,"title":775,"description":776,"published":777,"category":601,"image":778,"draft":605},"\u002Fblog\u002Fvibe-coded-app-security-checklist","La lista de seguridad del vibe coding, en nueve comprobaciones","Una lista de seguridad del vibe coding con nueve puntos, cada uno verificable en tu app desde fuera por cualquiera, y cada uno con una prueba de una línea.","2026-09-20","\u002Fblog\u002Fvibe-coded-app-security-checklist\u002Fcard-800x500.png",{"path":780,"title":781,"description":782,"published":783,"category":601,"image":784,"draft":605},"\u002Fblog\u002Fstripe-secret-key-in-frontend","Una clave secreta de Stripe en tu frontend puede mover dinero","Una clave secreta de Stripe expuesta en tu frontend puede reembolsar, cobrar y leer cada ficha de cliente que tienes. Tu clave pk_live_ sí debe estar ahí.","2026-09-19","\u002Fblog\u002Fstripe-secret-key-in-frontend\u002Fcard-800x500.png",{"path":172,"title":786,"description":787,"published":788,"category":601,"image":789,"draft":605},"Variables de entorno de Vite expuestas: el prefijo dice publica esto","Variables de entorno de Vite expuestas en tu app: hicieron lo que pedía el prefijo. VITE_ y NEXT_PUBLIC_ significan publica esto, y la IA nunca supo el coste.","2026-09-18","\u002Fblog\u002Fvite-and-next-public-env-vars\u002Fcard-800x500.png",{"path":791,"title":792,"description":793,"published":794,"category":601,"image":795,"draft":605},"\u002Fblog\u002Fbase44-source-maps","Seguridad en Base44: qué marca un escaneo y qué te toca arreglar a ti","Seguridad en Base44 en 5.438 apps escaneadas: tres hallazgos en casi todas son de la plataforma, el source map es la insignia de Base44 y lo tuyo es poco.","2026-09-17","\u002Fblog\u002Fbase44-source-maps\u002Fcard-800x500.png",{"path":797,"title":798,"description":799,"published":800,"category":601,"image":801,"draft":605},"\u002Fblog\u002Fis-cursor-ai-safe","¿Es seguro Cursor AI? El editor, el código y la app que publicaste","¿Es seguro Cursor AI? Tres preguntas en una búsqueda: qué guarda Cursor, en qué falla el código que escribe y si la app que publicaste está abierta.","2026-09-16","\u002Fblog\u002Fis-cursor-ai-safe\u002Fcard-800x500.png",{"path":212,"title":803,"description":804,"published":805,"category":601,"image":806,"draft":605},"¿Es seguro Replit? Lo que vimos en 3.042 aplicaciones Replit en vivo","¿Es seguro Replit? Pasamos 3.042 aplicaciones Replit en vivo por nueve comprobaciones externas. Los hallazgos estaban en la aplicación publicada, no en el host.","2026-09-15","\u002Fblog\u002Fis-replit-safe\u002Fcard-800x500.png",{"path":808,"title":809,"description":810,"published":811,"category":724,"image":812,"draft":605},"\u002Fblog\u002Fsupabase-storage-backup","Supabase storage backup: tu copia de la base no tiene archivos","Un Supabase storage backup es una tarea aparte. Las copias de la base guardan la lista de tus archivos y ninguno de ellos, así que cada upload queda roto.","2026-09-14","\u002Fblog\u002Fsupabase-storage-backup\u002Fcard-800x500.png",{"path":814,"title":815,"description":816,"published":817,"category":724,"image":818,"draft":605},"\u002Fblog\u002Fsupabase-point-in-time-recovery","Point-in-time recovery de Supabase: precio y límites","El point-in-time recovery de Supabase rebobina tu base de datos a cualquier segundo de la última semana. Cuesta $100 al mes sobre Pro y solo cubre la base.","2026-09-13","\u002Fblog\u002Fsupabase-point-in-time-recovery\u002Fcard-800x500.png",{"path":820,"title":821,"description":822,"published":823,"category":724,"image":824,"draft":605},"\u002Fblog\u002Fsupabase-project-paused-recover","¿Proyecto de Supabase pausado? Tus datos siguen ahí","Supabase pausó tu proyecto tras una semana sin actividad. No se ha borrado nada, Restaurar está junto al nombre y tienes un año antes de que eso cambie.","2026-09-12","\u002Fblog\u002Fsupabase-project-paused-recover\u002Fcard-800x500.png",{"path":826,"title":827,"description":828,"published":829,"category":601,"image":830,"draft":605},"\u002Fblog\u002Fsafest-ai-app-builder","¿Qué builder de apps con IA es más seguro? 30.998 apps escaneadas","¿Qué builder de apps con IA es más seguro? Escaneamos 30.998 apps activas de Lovable, Base44, Replit, v0 y Bolt. El builder no es lo que decide tu nota.","2026-09-11","\u002Fblog\u002Fsafest-ai-app-builder\u002Fcard-800x500.png",{"path":832,"title":833,"description":834,"published":835,"category":601,"image":836,"draft":605},"\u002Fblog\u002Fenable-rls-on-every-supabase-table","Activa Row Level Security en cada tabla de Supabase y compruébalo","Activar Row Level Security en Supabase sin política cierra la tabla del todo. Una política sin el interruptor no hace nada. Aquí tienes el SQL y la prueba.","2026-09-10","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fcard-800x500.png",{"path":838,"title":839,"description":840,"published":841,"category":601,"image":842,"draft":605},"\u002Fblog\u002Fsupabase-rls-disabled-in-public","Supabase \"RLS disabled in public\": lo que el aviso no ve","Supabase marca \"RLS disabled in public\" como error. No dice nada de la política de lectura que deja tu tabla igual de abierta a cualquiera.","2026-09-09","\u002Fblog\u002Fsupabase-rls-disabled-in-public\u002Fcard-800x500.png",{"path":473,"title":844,"description":845,"published":846,"category":601,"image":847,"draft":605},"Cómo rotar una clave service_role de Supabase filtrada","Supabase dice que primero cierres la fuga. Otras guías dicen que rotes ya. Cuál es lo correcto depende de dónde se filtró tu clave service_role.","2026-09-08","\u002Fblog\u002Frotate-supabase-service-role-key\u002Fcard-800x500.png",{"path":849,"title":850,"description":851,"published":852,"category":601,"image":853,"draft":605},"\u002Fblog\u002Fvibe-coding-security-scanners-compared","Escáneres de seguridad vibe coding comparados, el nuestro incluido","El mejor escáner de seguridad para vibe coding depende de tres preguntas que ninguna lista de funciones responde. Diez herramientas, con precios.","2026-09-07","\u002Fblog\u002Fvibe-coding-security-scanners-compared\u002Fcard-800x500.png",{"path":855,"title":856,"description":857,"published":858,"category":601,"image":859,"draft":605},"\u002Fblog\u002Fsupabase-security-checker","Supabase security checker: haz tú mismo las cinco comprobaciones","Un Supabase security checker lee tu app publicada en lugar de la configuración de tu proyecto. Estas son las cinco comprobaciones y cómo hacer cada una.","2026-09-06","\u002Fblog\u002Fsupabase-security-checker\u002Fcard-800x500.png",{"path":861,"title":862,"description":863,"published":864,"category":601,"image":865,"draft":605},"\u002Fblog\u002Fvibe-coding-security-scanner","Escáner de seguridad para vibe coding: qué se le escapa","Un escáner de seguridad para vibe coding lee tu app en vivo desde fuera. Qué cubre eso, las cuatro cosas que no puede ver y cómo leer el resultado.","2026-09-05","\u002Fblog\u002Fvibe-coding-security-scanner\u002Fcard-800x500.png",{"path":867,"title":868,"description":869,"published":870,"category":601,"image":871,"draft":605},"\u002Fblog\u002Fmissing-security-headers","Faltan cabeceras de seguridad: cuándo importa de verdad","Que falten cabeceras de seguridad es el hallazgo que más imprime nuestro escáner. Contra qué protegen y cuándo son la línea menos urgente de tu informe.","2026-09-04","\u002Fblog\u002Fmissing-security-headers\u002Fcard-800x500.png",{"path":873,"title":874,"description":875,"published":876,"category":601,"image":877,"draft":605},"\u002Fblog\u002Fopenai-api-key-exposed-in-frontend","Tu clave de API de OpenAI está expuesta en tu frontend. Rótala.","Una clave de API de OpenAI expuesta en tu frontend no se puede atar a un dominio. Rótala hoy, mueve la llamada a tu servidor y limita el gasto.","2026-09-03","\u002Fblog\u002Fopenai-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":440,"title":879,"description":880,"published":881,"category":601,"image":882,"draft":605},"Clave de API expuesta en el frontend: qué llevan 30.998 apps","Una clave de API expuesta en tu frontend suele ser una clave de Google Maps. Escaneamos 30.998 apps vibe-coded y contamos qué secretos se filtran de verdad.","2026-09-02","\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps\u002Fcard-800x500.png",{"path":884,"title":885,"description":886,"published":887,"category":724,"image":888,"draft":605},"\u002Fblog\u002Fsupabase-backup-tools-compared","Herramientas de backup de Supabase comparadas, la nuestra incluida","Cuatro tipos de herramienta de backup de Supabase, qué copia cada una y cuándo una GitHub Action gratuita le gana a pagar a cualquiera, nosotros incluidos.","2026-09-01","\u002Fblog\u002Fsupabase-backup-tools-compared\u002Fcard-800x500.png",{"path":890,"title":891,"description":892,"published":893,"category":601,"image":894,"draft":605},"\u002Fblog\u002Freplit-secrets-explained","Cómo usar secrets en Replit, y qué se publica de todos modos","Cómo usar secrets en Replit: añadir uno, leerlo y arreglar las dos causas del undefined. Y las claves que la herramienta Secrets no puede mantener privadas.","2026-08-31","\u002Fblog\u002Freplit-secrets-explained\u002Fcard-800x500.png",{"path":896,"title":897,"description":898,"published":899,"category":724,"image":900,"draft":605},"\u002Fblog\u002Fback-up-supabase-free-tier","Backups del plan gratuito de Supabase: cómo hacer uno sin terminal","No hay backups en el plan gratuito de Supabase: la copia tienes que hacerla tú. Cómo sacarla desde el panel y qué deja fuera la vía CSV.","2026-08-30","\u002Fblog\u002Fback-up-supabase-free-tier\u002Fcard-800x500.png",{"path":902,"title":903,"description":904,"published":905,"category":601,"image":906,"draft":605},"\u002Fblog\u002Fis-supabase-secure","¿Supabase es seguro? Sí. Tu proyecto es otra pregunta","¿Supabase es seguro? La plataforma está auditada, cifrada y sometida a pentests. Su propia documentación dice dónde termina eso y empiezan tus ajustes.","2026-08-29","\u002Fblog\u002Fis-supabase-secure\u002Fcard-800x500.png",{"path":908,"title":909,"description":910,"published":911,"category":601,"image":912,"draft":605},"\u002Fblog\u002Fwhere-to-find-supabase-api-keys","Dónde están tus claves API de Supabase: anon, service_role y URL","La URL del proyecto, la clave anon y la clave service_role están en una sola página del panel. Aquí tienes dónde está, y cuál de los cuatro va en tu app.","2026-08-28","\u002Fblog\u002Fwhere-to-find-supabase-api-keys\u002Fcard-800x500.png",{"path":914,"title":915,"description":916,"published":917,"category":601,"image":918,"draft":605},"\u002Fblog\u002Fnew-row-violates-row-level-security-policy","New row violates row-level security policy en Supabase. ¿Y ahora?","\"New row violates row-level security policy\" significa que Supabase rechazó una escritura. El arreglo rápido vuelve a abrir la tabla para cualquiera.","2026-08-27","\u002Fblog\u002Fnew-row-violates-row-level-security-policy\u002Fcard-800x500.png",{"path":920,"title":921,"description":922,"published":923,"category":601,"image":924,"draft":605},"\u002Fblog\u002Fcors-wildcard-security-risk","¿Es un comodín CORS un riesgo de seguridad? Casi nunca.","¿Es un comodín CORS un riesgo de seguridad? Casi siempre es el ajuste por defecto de tu builder y no entrega nada que tu servidor no diera ya a cualquiera.","2026-08-26","\u002Fblog\u002Fcors-wildcard-security-risk\u002Fcard-800x500.png",{"path":926,"title":927,"description":928,"published":929,"category":724,"image":930,"draft":605},"\u002Fblog\u002Fsupabase-branching-is-not-a-backup","Supabase branching no es un backup. Solo va hacia adelante.","Por qué el branching de Supabase no es un backup: una rama arranca sin tus datos y un merge solo mueve el esquema. Para qué sirve y qué usar en su lugar.","2026-08-25","\u002Fblog\u002Fsupabase-branching-is-not-a-backup\u002Fcard-800x500.png",{"path":932,"title":933,"description":934,"published":935,"category":724,"image":936,"draft":605},"\u002Fblog\u002Fhow-to-restore-a-supabase-backup","Cómo restaurar un backup de Supabase, y qué se rompe después","Cómo restaurar un backup de Supabase desde el panel o desde un archivo de volcado, qué reemplaza la restauración y por qué tu app puede seguir rota al terminar.","2026-08-24","\u002Fblog\u002Fhow-to-restore-a-supabase-backup\u002Fcard-800x500.png",{"path":938,"title":939,"description":940,"published":941,"category":601,"image":942,"draft":605},"\u002Fblog\u002Fsupabase-storage-bucket-public","Tu bucket de Supabase Storage es público. ¿Es un problema?","Un bucket público de Supabase Storage significa que quien tenga la URL de un archivo puede abrirlo. No significa que alguien pueda listar lo que hay dentro.","2026-08-23","\u002Fblog\u002Fsupabase-storage-bucket-public\u002Fcard-800x500.png",{"path":944,"title":945,"description":946,"published":947,"category":601,"image":948,"draft":605},"\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend","¿Es un problema una clave de API de Google en tu frontend?","Una clave de API de Google en tu frontend es la clave que más encuentra nuestro escáner, y casi siempre no pasa nada. Un ajuste gratuito decide cuál es cuál.","2026-08-22","\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":950,"title":951,"description":952,"published":953,"category":724,"image":954,"draft":605},"\u002Fblog\u002Fai-agent-deleted-my-database","Un agente de IA borró mis datos de Supabase. ¿Qué puedo recuperar?","Un agente de IA borró datos de tu base. Lo que puedes recuperar ya estaba decidido antes de que se ejecutara, y los próximos minutos deciden el resto.","2026-08-21","\u002Fblog\u002Fai-agent-deleted-my-database\u002Fcard-800x500.png",{"path":956,"title":957,"description":958,"published":959,"category":601,"image":960,"draft":605},"\u002Fblog\u002Fcan-anyone-read-your-supabase-database","¿Puede cualquiera leer tu base de datos Supabase? 3.680 apps","¿Puede cualquiera leer tu base de datos Supabase sin iniciar sesión? Escaneamos 30.998 apps activas hechas con builders de IA y medimos cuántas dicen que sí.","2026-08-18","\u002Fblog\u002Fcan-anyone-read-your-supabase-database\u002Fcard-800x500.png",{"path":962,"title":963,"description":964,"published":959,"category":601,"image":965,"draft":605},"\u002Fblog\u002Fsource-maps-exposed-in-production","Source maps expuestos: tu app está publicando su código original","Un source map expuesto deja que cualquiera lea el código original de tu app, comentarios incluidos. La comprobación de 30 segundos y lo que de verdad importa.","\u002Fblog\u002Fsource-maps-exposed-in-production\u002Fcard-800x500.png",{"path":967,"title":968,"description":969,"published":970,"category":601,"image":971,"draft":605},"\u002Fblog\u002Fsupabase-new-api-keys","Las nuevas claves de API de Supabase: ¿cuál va en tu app?","Supabase sustituyó anon y service_role por claves publicables y secretas. ¿Cuál pertenece a tu app y cuál no debe estar nunca?","2026-08-12","\u002Fblog\u002Fsupabase-new-api-keys\u002Fcard-800x500.png",{"path":973,"title":974,"description":975,"published":976,"category":724,"image":977,"draft":605},"\u002Fblog\u002Fdoes-supabase-back-up-my-database","¿Supabase respalda mi base de datos? Depende de tu plan.","¿Supabase respalda tu base de datos? A diario en los planes de pago, y nada en el gratuito. Cómo saber cuál tienes y qué es lo que esa copia no cubre.","2026-08-11","\u002Fblog\u002Fdoes-supabase-back-up-my-database\u002Fcard-800x500.png",{"path":979,"title":980,"description":981,"published":982,"category":601,"image":983,"draft":605},"\u002Fblog\u002Fsupabase-rls-on-but-table-still-public","Supabase Row Level Security está activado. Tu tabla sigue pública.","Activar Supabase Row Level Security no protege una tabla. Lo hacen tus políticas, y la que arregló tu app rota puede dejar entrar a cualquiera.","2026-08-10","\u002Fblog\u002Fsupabase-rls-on-but-table-still-public\u002Fcard-800x500.png",{"path":985,"title":986,"description":987,"published":982,"category":724,"image":988,"draft":605},"\u002Fblog\u002Fversion-history-is-not-a-backup","El historial de versiones no es un backup. No recupera una tabla.","Lovable y Bolt guardan un historial de versiones de tu código. Tu base de datos es un servicio aparte, y volver atrás no te devuelve tus datos.","\u002Fblog\u002Fversion-history-is-not-a-backup\u002Fcard-800x500.png",{"path":497,"title":990,"description":991,"published":992,"category":724,"image":993,"draft":605},"Tres formas de respaldar una base Supabase, y qué falta en cada una","El panel, pg_dump y un servicio gestionado. Qué guarda de verdad cada uno, qué deja fuera sin avisar y cuál sobrevive a perder la cuenta.","2026-08-09","\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database\u002Fcard-800x500.png",{"path":995,"title":996,"description":997,"published":992,"category":601,"image":998,"draft":605},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","Qué claves de API son seguras en el navegador y cuáles no","Tu clave anon de Supabase está pensada para ser pública. Tu clave service_role no, y se salta todas las reglas que pongas. Cómo distinguirlas.","\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend\u002Fcard-800x500.png",1791705962974]