[{"data":1,"prerenderedAt":584},["ShallowReactive",2],{"blog-es-replit-secrets-explained":3,"blog-index-es":342},{"id":4,"title":5,"body":6,"category":299,"cover":300,"coverAlt":301,"description":302,"draft":303,"extension":304,"faq":305,"image":320,"keywords":321,"meta":328,"navigation":329,"ogTitle":330,"path":331,"published":332,"seo":333,"stem":334,"tldr":335,"updated":340,"__hash__":341},"blog_es\u002Fblog\u002Freplit-secrets-explained.md","Cómo usar secrets en Replit, y qué se publica de todos modos",{"type":7,"value":8,"toc":288},"minimark",[9,13,21,24,33,38,41,80,83,90,94,97,100,103,107,110,113,116,122,136,147,160,167,171,174,184,190,195,205,208,212,215,218,221,232,238,246,250,276],[10,11,12],"p",{},"En algún momento entre construir tu aplicación y publicarla, Replit te dijo que\ndejaras de poner tu clave de API en el código. Así que buscaste cómo usar\nsecrets en Replit, moviste la clave a la herramienta Secrets y el aviso\ndesapareció. Luego alguien te dijo que la clave sigue visible en tu aplicación\npublicada, y las dos cosas parecen ciertas a la vez.",[10,14,15,16,20],{},"Lo son. Esta es la parte que la mayoría de los consejos sobre esto se dejan\nfuera: ",[17,18,19],"strong",{},"la herramienta Secrets decide dónde se guarda un valor. Tu código\ndecide adónde se lleva."," Son dos preguntas distintas, y solo la primera tiene\nalgo que ver con la herramienta.",[10,22,23],{},"En Replit esto aprieta más que en ningún otro sitio, porque la mitad de tu\naplicación que se ejecuta en la máquina de Replit y la mitad que se ejecuta en\nel portátil de tu visitante viven en el mismo proyecto, a menudo en archivos\ncontiguos. Nada en el editor traza una línea entre ellas.",[10,25,26,27,32],{},"Entre el 12 y el 14 de agosto de 2026 pasamos las mismas nueve comprobaciones\nexternas por 30.998 aplicaciones activas, de las cuales 3.042 estaban publicadas\nen Replit. En 219 de esas aplicaciones de Replit había algo con forma de clave\ndentro del código que descarga un visitante. En el conjunto de la muestra, la\nmayor parte de lo que encuentra esa comprobación es una clave de Google, que con\nrestricciones suele estar bien. Las que no están bien son justo las que una\nherramienta de secrets debía haber evitado. Las cifras completas están en\n",[28,29,31],"a",{"href":30},"\u002Fresearch\u002Fvibe-coded-app-security-2026","nuestro informe de escaneo",".",[34,35,37],"h2",{"id":36},"cómo-uso-secrets-en-replit","¿Cómo uso secrets en Replit?",[10,39,40],{},"Abre la herramienta Secrets, añade un nombre y un valor, y lee ese valor en tu\ncódigo como variable de entorno. Lleva alrededor de un minuto.",[42,43,44,52,64,67,77],"ol",{},[45,46,47,48,51],"li",{},"En tu proyecto, abre ",[17,49,50],{},"Secrets",". Está en la lista de herramientas, y buscar\nla palabra en ese panel lo encuentra.",[45,53,54,55,58,59,63],{},"Elige ",[17,56,57],{},"+ New secret",". Ponle un nombre en mayúsculas con guiones bajos, como\n",[60,61,62],"code",{},"OPENAI_API_KEY",". Ese nombre es el que usará tu código, así que importa más\nde lo que parece.",[45,65,66],{},"Pega el valor en el segundo campo y guarda. Replit lo cifra y lo mantiene\nfuera de los archivos de tu proyecto.",[45,68,69,70,73,74,32],{},"Léelo en tu código. En JavaScript es ",[60,71,72],{},"process.env.OPENAI_API_KEY",", y en\nPython es ",[60,75,76],{},"os.getenv(\"OPENAI_API_KEY\")",[45,78,79],{},"Vuelve atrás y borra el valor de donde estuviera antes.",[10,81,82],{},"El paso cinco es el que la gente se salta, y del que depende que todo esto haya\nservido de algo. Crear un secret no elimina la copia que ya tenías. Una clave\npegada en un archivo la semana pasada sigue en ese archivo, sigue en el\nhistorial de tu proyecto y sigue dentro de cada copia de tu aplicación publicada\ndesde entonces.",[10,84,85,86,89],{},"Un archivo ",[60,87,88],{},".env"," hace el mismo trabajo que la herramienta Secrets, con una\ndiferencia que importa: es un archivo, así que viaja con el proyecto cuando\nalguien lo bifurca o lo conecta a un repositorio.",[34,91,93],{"id":92},"son-seguros-los-secrets-de-replit","¿Son seguros los secrets de Replit?",[10,95,96],{},"Para lo que hacen, sí. El valor está cifrado, queda fuera de tu código fuente, y\nlas tres formas más comunes de que a alguien se le escape una clave quedan\ncerradas con eso: compartes tu proyecto con un colaborador, lo conectas a un\nrepositorio, o alguien te mira trabajar.",[10,98,99],{},"Piénsalo como un cajón cerrado con llave. Lo que hay dentro del cajón queda\nfuera de la vista de cualquiera que lea tus archivos. Lo que el cajón no puede\ndecidir es qué hace tu aplicación con el contenido una vez que tu propio código\nlo ha abierto y se ha marchado con él.",[10,101,102],{},"Y una aplicación de Replit publicada se marcha con bastante. A cada visitante\nque carga tu sitio se le envía toda la mitad delantera, porque un navegador no\npuede dibujar una página que no ha recibido. Si el código que abre el cajón es\ncódigo que se envía a los visitantes, el valor que sacó viaja con él.",[34,104,106],{"id":105},"qué-mitad-de-tu-aplicación-lee-la-clave","¿Qué mitad de tu aplicación lee la clave?",[10,108,109],{},"La mitad que se ejecuta en la máquina de Replit puede leer un secret sin\npeligro. La mitad que se ejecuta en el navegador de tu visitante no puede, y la\nforma habitual de hacer que funcione es también la forma en que la clave se\nvuelve pública.",[10,111,112],{},"Tu código de servidor es la parte que ejecuta Replit: una ruta de Express, un\nmanejador de Python, una función que habla con OpenAI o con Stripe y le devuelve\nuna respuesta a tu aplicación. Lee un secret, lo usa, y el valor nunca sale de\nla máquina.",[10,114,115],{},"Tu código de navegador es todo lo que ejecuta el portátil de tu visitante. En un\nproyecto de React es la mayor parte de lo que has estado editando. Se compila en\nun paquete de JavaScript y lo descarga entero cualquiera que abra tu sitio.",[117,118],"diagram",{"alt":119,"caption":120,"src":121},"Un almacén cerrado de valores dentro de un marco discontinuo que representa la máquina de Replit, con dos caminos de salida. El camino superior llega a un servidor que se queda dentro del marco, donde el valor sigue dibujado como puntos ocultos y lleva una marca de verificación. El camino inferior llega a una ventana de navegador marcada VITE_, luego cruza el marco y termina en una persona que sostiene el mismo valor como una barra legible, tachada.","Un cajón, dos lectores. El valor va adonde vaya el código que lo abrió.","\u002Fblog\u002Freplit-secrets-explained\u002Fwhich-half-reads-it-1600x760.png",[10,123,124,127,128,131,132,135],{},[60,125,126],{},"process.env"," no existe en un navegador, así que el código de navegador que lo\nlee no obtiene nada. Para que el valor llegue, alguien lo renombra:\n",[60,129,130],{},"VITE_OPENAI_API_KEY"," en un proyecto de Vite, o ",[60,133,134],{},"NEXT_PUBLIC_OPENAI_API_KEY"," en\nuno de Next.js. Funciona de inmediato, porque ese prefijo es una instrucción a\nla herramienta de compilación para escribir el valor dentro del paquete. La\npropia documentación de Vite lo dice con esas palabras y desaconseja poner ahí\nclaves de API por ese mismo motivo.",[10,137,138,139,142,143,146],{},"Así que la comprobación más rápida de este artículo es una búsqueda. Abre tu\nproyecto y busca ",[60,140,141],{},"VITE_"," y ",[60,144,145],{},"NEXT_PUBLIC_",". Cada coincidencia es un valor que tu\nherramienta de compilación tiene orden de publicar.",[10,148,149,150,154,155,159],{},"Para algunos eso es correcto. Una clave publicable de Supabase está diseñada\npara vivir en un navegador, y una clave de Google Maps con una\n",[28,151,153],{"href":152},"\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend","restricción de referente"," también. Es\nincorrecto para todo lo que gasta dinero o lee una base de datos sin preguntar\nquién llama, y\n",[28,156,158],{"href":157},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","distinguir las dos"," lleva\nalrededor de un minuto por clave.",[10,161,162,163,32],{},"Si prefieres ver qué está repartiendo tu aplicación publicada antes de ir\narchivo por archivo, nuestro escaneo gratuito lee tu sitio desde fuera y te dice\nqué encuentra ahí. Tarda unos 20 segundos y no necesita cuenta:\n",[28,164,166],{"href":165},"\u002Fsecurity-scanner","escanea tu aplicación",[34,168,170],{"id":169},"por-qué-no-funciona-mi-secret-de-replit","¿Por qué no funciona mi secret de Replit?",[10,172,173],{},"Dos motivos, y desde donde estás producen el mismo síntoma: un valor vacío y una\naplicación que no funciona.",[10,175,176,179,180,183],{},[17,177,178],{},"El código que lo lee se ejecuta en el navegador."," Ahí no hay ningún entorno\nque leer, así que ",[60,181,182],{},"process.env.TU_CLAVE"," está vacío y lo seguirá estando. Esto\nno es un problema de configuración, y volver a crear el secret las veces que\nhaga falta no lo mueve. La llamada que necesita la clave tiene que mudarse a la\nmitad de servidor de tu aplicación.",[10,185,186,189],{},[17,187,188],{},"Tu aplicación publicada está corriendo una versión anterior."," Replit mantiene\ndos conjuntos de valores, los de tu espacio de trabajo y aquellos con los que\ncorre tu aplicación publicada. Se sincronizan, así que un secret que añadas\nllega normalmente al despliegue. Lo que la aplicación en marcha usa de verdad,\nsin embargo, es lo que había la última vez que la publicaste. Añade un secret\ndespués y la aplicación en marcha no sabrá nada de él hasta que vuelvas a\npublicar.",[117,191],{"alt":192,"caption":193,"src":194},"Dos paneles uno junto a otro. En el panel del editor el almacén cerrado contiene un valor lleno y la vista previa de al lado lleva una marca de verificación. En el panel de la aplicación publicada el mismo almacén tiene una ranura vacía, la aplicación en marcha de al lado está tachada y debajo aparece la palabra undefined.","El mismo nombre en los dos sitios. La aplicación en marcha funciona con los valores que había la última vez que publicaste.","\u002Fblog\u002Freplit-secrets-explained\u002Ftwo-stores-one-name-1600x560.png",[10,196,197,198,201,202,204],{},"La propia guía de Replit para una aplicación que funciona en el editor y se\nrompe al publicarse empieza exactamente en este punto, así que vale la pena\nabrir los secrets de despliegue y leer los nombres antes de dar nada por roto.\nUn nombre escrito ",[60,199,200],{},"OPENAI_KEY"," en un sitio y ",[60,203,62],{}," en el otro produce\nel mismo valor vacío que un secret que falta.",[10,206,207],{},"Un despliegue que falla a medianoche es cuando se toma el atajo. Pegar el valor\ndirectamente en el código desbloquea la situación en segundos, la aplicación\nvuelve, y la clave queda en tu paquete publicado a partir de ese momento.",[34,209,211],{"id":210},"la-clave-ya-está-en-mi-aplicación-publicada-y-ahora","La clave ya está en mi aplicación publicada. ¿Y ahora?",[10,213,214],{},"Rótala, antes de cambiar nada de código. En el panel del proveedor, genera una\nclave nueva y revoca la vieja.",[10,216,217],{},"Ese orden importa porque la rotación es el único paso que hace que el valor\nexpuesto deje de funcionar. Editar tu código lo quita de la versión actual y lo\ndeja en el historial de tu proyecto, y no hace absolutamente nada con las copias\nde tu paquete que ya se han descargado, cacheado y rastreado. Que tu aplicación\nsea pequeña tampoco ayuda: los rastreadores automáticos leen sitios públicos\nbuscando cadenas con forma de clave sin parar, sin la menor idea de quién eres.",[10,219,220],{},"Después, en este orden:",[42,222,223,226,229],{},[45,224,225],{},"Pon la clave nueva en Secrets y léela solo desde código de servidor.",[45,227,228],{},"Mueve la llamada que la necesitaba. Todo lo que hable con OpenAI, Anthropic,\nStripe o con tu base de datos usando una clave administrativa va detrás de\nuna ruta a la que llame tu aplicación, de modo que el navegador le pregunte a\ntu servidor y tu servidor sea quien guarde la clave.",[45,230,231],{},"Revisa las páginas de uso y facturación del proveedor para el periodo en que\nla clave vieja estuvo pública. La rotación detiene lo que pase a partir de\nahora y no dice nada de lo que ya pasó.",[10,233,234,235,237],{},"Las claves de proveedores de modelos son las primeras que hay que revisar en\nReplit. ",[60,236,62],{}," es el ejemplo al que recurre la propia documentación de\nReplit cuando te enseña a añadir un secret, y de una clave de OpenAI o Anthropic\nno existe variante publicable. Cada una de ellas factura directamente a tu\ncuenta.",[10,239,240,241,245],{},"Un sitio más donde mirar ya que estás: si tu proyecto publica\n",[28,242,244],{"href":243},"\u002Fblog\u002Fsource-maps-exposed-in-production","source maps",", un visitante puede leer\nese paquete como los archivos originales que escribiste, con tus propios nombres\nde variables todavía puestos.",[34,247,249],{"id":248},"qué-hacer-esta-semana","Qué hacer esta semana",[251,252,253],"key-takeaways",{},[254,255,256,259,267,270,273],"ul",{},[45,257,258],{},"Mueve todas tus claves a la herramienta Secrets y luego borra las copias que dejaste en archivos. Crear un secret no elimina el valor antiguo.",[45,260,261,262,142,264,266],{},"Busca en tu proyecto ",[60,263,141],{},[60,265,145],{},". Cada coincidencia es un valor que tu herramienta de compilación publica a propósito, y cada uno tiene que ser una clave que se podía publicar.",[45,268,269],{},"Para cualquiera que no lo sea, mueve la llamada que la usa a tu mitad de servidor, de modo que el navegador le pregunte a tu aplicación y sea tu aplicación la que guarde la clave.",[45,271,272],{},"Si un secret aparece vacío en la aplicación publicada pero funciona en el editor, publica otra vez y comprueba el nombre en tus secrets de despliegue antes de tocar el código.",[45,274,275],{},"Rota en el proveedor todo lo que ya haya salido, antes de tocar el código. Después lee la página de facturación de las semanas en que estuvo público.",[10,277,278,279,283,284,32],{},"Haz primero la búsqueda. Lleva un minuto, no necesita instalar nada y te dice\ncuáles de las claves de tu proyecto ya son públicas. La\n",[28,280,282],{"href":281},"\u002Fchecklist","lista de seguridad de 10 minutos"," cubre el resto de lo que conviene\nconfirmar en una aplicación recién lanzada, y la guía en lenguaje llano para\nesta plataforma es\n",[28,285,287],{"href":286},"\u002Fis-your-replit-app-safe","¿es segura tu aplicación de Replit?",{"title":289,"searchDepth":290,"depth":290,"links":291},"",3,[292,294,295,296,297,298],{"id":36,"depth":293,"text":37},2,{"id":92,"depth":293,"text":93},{"id":105,"depth":293,"text":106},{"id":169,"depth":293,"text":170},{"id":210,"depth":293,"text":211},{"id":248,"depth":293,"text":249},"Fundamentos de seguridad","\u002Fblog\u002Freplit-secrets-explained\u002Fcover-1200x630.png","El logotipo de Replit, una flecha hacia un almacén cerrado de valores ocultos y otra hacia la aplicación en marcha que los lee.","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.",false,"md",[306,308,311,314,317],{"q":93,"a":307},"Para lo que hacen, sí. Replit cifra los valores y los mantiene fuera de tus archivos, así que compartir tu proyecto, conectarlo a un repositorio o retransmitir mientras trabajas ya no entrega la clave a quien esté mirando. Lo que la herramienta no puede decidir es adónde lleva tu aplicación ese valor después. Una clave que lee código ejecutado en la máquina de Replit se queda en Replit. La misma clave leída por código que se ejecuta en el navegador de tu visitante queda incrustada en lo que publicas, y haberla guardado antes en Secrets no cambia nada de eso.",{"q":309,"a":310},"¿Por qué mi secret de Replit sale undefined?","Hay dos causas y desde donde estás se ven iguales. O el código que lo lee se ejecuta en el navegador, donde no hay ningún entorno que leer y process.env no contiene nada, o tu aplicación publicada está corriendo una versión desplegada antes de que crearas el secret. Para lo segundo, publica otra vez: una aplicación en marcha usa los valores que había la última vez que salió.",{"q":312,"a":313},"¿Puedo usar un secret en mi frontend de React en Replit?","Puedes poner un valor ahí, y no será secreto. El código de React se ejecuta en la máquina de tu visitante, así que todo lo que lea tiene que enviarse antes a esa máquina. Las herramientas de compilación lo hacen explícito con un prefijo: Vite solo expone al código del navegador las variables que empiezan por VITE_, y Next.js solo las que empiezan por NEXT_PUBLIC_. Añadir el prefijo es como la gente consigue que una clave funcione en el frontend, y es también el momento en que esa clave se vuelve pública. Las claves publicables van ahí. Todo lo que gasta dinero o lee una base de datos va en el servidor.",{"q":315,"a":316},"¿Tengo que volver a añadir mis secrets al publicar?","Normalmente no, porque los secrets de despliegue se sincronizan con los de tu espacio de trabajo, pero el valor que usa tu aplicación en marcha es el que estaba presente en tu última publicación. Un secret añadido después llega al despliegue en la siguiente. La propia guía de Replit para una aplicación que funciona en el editor y falla al publicarse empieza aquí, así que si algo faltó al desplegar, abre los secrets de despliegue y comprueba que el nombre esté y esté escrito igual.",{"q":318,"a":319},"Pegué una clave de API en un archivo antes de encontrar la herramienta Secrets. ¿Basta con borrar el archivo?","No. Rota primero la clave en el proveedor, que es lo que cierra la puerta de verdad, y después mueve el valor a Secrets. Borrar una línea de código la quita de la versión actual y no del historial de tu proyecto, ni de ninguna copia de tu aplicación publicada que alguien ya tenga. La rotación es el único paso que hace que el valor antiguo deje de funcionar, y suele llevar cerca de un minuto en el panel del proveedor.","\u002Fblog\u002Freplit-secrets-explained\u002Fcard-800x500.png",[322,323,324,325,326,327],"cómo usar secrets en replit","replit secrets","replit secrets no funcionan","son seguros los secrets de replit","variables de entorno replit","secret replit",{},true,"Cómo usar secrets en Replit","\u002Fblog\u002Freplit-secrets-explained","2026-08-31",{"title":5,"description":302},"blog\u002Freplit-secrets-explained",[336,337,338,339],"Cómo usar secrets en Replit: abre la herramienta Secrets, añade un nombre y un valor, y lee ese valor en tu código como variable de entorno.","Eso mantiene la clave fuera de tus archivos. No la mantiene fuera de tu aplicación publicada, porque lo que lee tu código de navegador queda incrustado en lo que descarga cada visitante.","La señal es el nombre. Una variable que empieza por VITE_ o NEXT_PUBLIC_ la puso en el navegador tu herramienta de compilación a propósito.","Si un secret aparece vacío en la aplicación publicada, casi siempre es que la versión en marcha se publicó antes de crearlo. Publica otra vez.","2026-09-21","I5J-qEaBTxiUFjFiIbky2I4DJ7IT-YDJ_Ig9xqy3qTU",[343,350,356,361,367,373,379,385,391,397,403,409,415,421,427,433,439,445,451,457,463,469,475,481,482,488,494,500,506,512,518,524,530,535,541,547,551,557,563,569,574,580],{"path":344,"title":345,"description":346,"published":347,"category":348,"image":349,"draft":303},"\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","Backups","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",{"path":351,"title":352,"description":353,"published":354,"category":299,"image":355,"draft":303},"\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":357,"title":358,"description":359,"published":340,"category":299,"image":360,"draft":303},"\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.","\u002Fblog\u002Fis-lovable-safe\u002Fcard-800x500.png",{"path":362,"title":363,"description":364,"published":365,"category":299,"image":366,"draft":303},"\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":368,"title":369,"description":370,"published":371,"category":299,"image":372,"draft":303},"\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":374,"title":375,"description":376,"published":377,"category":299,"image":378,"draft":303},"\u002Fblog\u002Fvite-and-next-public-env-vars","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":380,"title":381,"description":382,"published":383,"category":299,"image":384,"draft":303},"\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":386,"title":387,"description":388,"published":389,"category":299,"image":390,"draft":303},"\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":392,"title":393,"description":394,"published":395,"category":299,"image":396,"draft":303},"\u002Fblog\u002Fis-replit-safe","¿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":398,"title":399,"description":400,"published":401,"category":348,"image":402,"draft":303},"\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":404,"title":405,"description":406,"published":407,"category":348,"image":408,"draft":303},"\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":410,"title":411,"description":412,"published":413,"category":348,"image":414,"draft":303},"\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":416,"title":417,"description":418,"published":419,"category":299,"image":420,"draft":303},"\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":422,"title":423,"description":424,"published":425,"category":299,"image":426,"draft":303},"\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":428,"title":429,"description":430,"published":431,"category":299,"image":432,"draft":303},"\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":434,"title":435,"description":436,"published":437,"category":299,"image":438,"draft":303},"\u002Fblog\u002Frotate-supabase-service-role-key","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":440,"title":441,"description":442,"published":443,"category":299,"image":444,"draft":303},"\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":446,"title":447,"description":448,"published":449,"category":299,"image":450,"draft":303},"\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":452,"title":453,"description":454,"published":455,"category":299,"image":456,"draft":303},"\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":458,"title":459,"description":460,"published":461,"category":299,"image":462,"draft":303},"\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":464,"title":465,"description":466,"published":467,"category":299,"image":468,"draft":303},"\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":470,"title":471,"description":472,"published":473,"category":299,"image":474,"draft":303},"\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps","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":476,"title":477,"description":478,"published":479,"category":348,"image":480,"draft":303},"\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":331,"title":5,"description":302,"published":332,"category":299,"image":320,"draft":303},{"path":483,"title":484,"description":485,"published":486,"category":348,"image":487,"draft":303},"\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":489,"title":490,"description":491,"published":492,"category":299,"image":493,"draft":303},"\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":495,"title":496,"description":497,"published":498,"category":299,"image":499,"draft":303},"\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":501,"title":502,"description":503,"published":504,"category":299,"image":505,"draft":303},"\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":507,"title":508,"description":509,"published":510,"category":299,"image":511,"draft":303},"\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":513,"title":514,"description":515,"published":516,"category":348,"image":517,"draft":303},"\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":519,"title":520,"description":521,"published":522,"category":348,"image":523,"draft":303},"\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":525,"title":526,"description":527,"published":528,"category":299,"image":529,"draft":303},"\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":152,"title":531,"description":532,"published":533,"category":299,"image":534,"draft":303},"¿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":536,"title":537,"description":538,"published":539,"category":348,"image":540,"draft":303},"\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":542,"title":543,"description":544,"published":545,"category":299,"image":546,"draft":303},"\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":243,"title":548,"description":549,"published":545,"category":299,"image":550,"draft":303},"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":552,"title":553,"description":554,"published":555,"category":299,"image":556,"draft":303},"\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":558,"title":559,"description":560,"published":561,"category":348,"image":562,"draft":303},"\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":564,"title":565,"description":566,"published":567,"category":299,"image":568,"draft":303},"\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":570,"title":571,"description":572,"published":567,"category":348,"image":573,"draft":303},"\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":575,"title":576,"description":577,"published":578,"category":348,"image":579,"draft":303},"\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database","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":157,"title":581,"description":582,"published":578,"category":299,"image":583,"draft":303},"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",1790150954121]