[{"data":1,"prerenderedAt":1054},["ShallowReactive",2],{"blog-es-certificate-not-trusted":3,"blog-index-es":523},{"id":4,"title":5,"body":6,"category":481,"cover":482,"coverAlt":483,"description":484,"draft":485,"extension":486,"faq":487,"image":503,"keywords":504,"meta":512,"navigation":513,"ogTitle":5,"path":514,"published":515,"seo":516,"stem":517,"tldr":518,"updated":515,"__hash__":522},"blog_es\u002Fblog\u002Fcertificate-not-trusted.md","Certificado no confiable: tres causas aparte de la caducidad",{"type":7,"value":8,"toc":467},"minimark",[9,13,16,25,30,33,36,39,131,134,137,141,144,156,186,189,200,204,207,210,238,244,247,251,254,257,260,263,267,270,273,276,281,299,303,306,309,333,338,341,359,363,366,369,376,384,388,391,399,410,419,430,434,459],[10,11,12],"p",{},"Ayer tu aplicación cargaba sin problemas. Hoy alguien te manda una captura de\nun aviso del navegador a pantalla completa, que dice que la conexión no es\nprivada, y te pregunta si te han hackeado la web. Abres el certificado y es\nválido hasta la próxima primavera. No ha caducado, y aun así el navegador dice\nque el certificado no es de confianza.",[10,14,15],{},"Lo obvio es renovarlo, y para esta pantalla es lo equivocado. Cada una de las\ntres causas de abajo le pasa a un certificado que ya está en fecha, así que una\nrenovación te da una fecha de caducidad más lejana en un certificado que se\nsigue rechazando por otro motivo.",[10,17,18,19,24],{},"En ",[20,21,23],"a",{"href":22},"\u002Fblog\u002Fdomain-and-certificate-expiry","nuestro artículo sobre la caducidad",",\nel certificado es la licencia del escaparate que dice que esta tienda es de\nverdad la del cartel. El navegador de un visitante lee tres cosas en esa licencia\nantes de dejar pasar a nadie: la fecha, el nombre de la tienda para la que se\nemitió y la firma de quien la emitió. La caducidad es la fecha. Este artículo\ntrata de las otras dos.",[26,27,29],"h2",{"id":28},"por-qué-sale-certificado-no-confiable-si-no-ha-caducado","¿Por qué sale certificado no confiable si no ha caducado?",[10,31,32],{},"Porque falló el nombre o la firma, y el navegador levanta el mismo muro para\ncada una de sus comprobaciones.",[10,34,35],{},"Un certificado solo es de confianza si nombra exactamente la dirección que hay en\nla barra del visitante y lo firmó una autoridad en la que el navegador ya\nconfía, con cada certificado intermedio enviado junto a él. Si falla cualquiera\nde las dos, Chrome muestra el aviso de que la conexión no es privada y Firefox el\nde un posible riesgo de seguridad, exactamente igual que con uno caducado.",[10,37,38],{},"Lo que cambia es la letra pequeña bajo el aviso. Léela antes de tocar nada:",[40,41,42,61],"table",{},[43,44,45],"thead",{},[46,47,48,52,55,58],"tr",{},[49,50,51],"th",{},"Lo que muestra Chrome",[49,53,54],{},"Lo que dice la explicación de Firefox",[49,56,57],{},"Qué significa",[49,59,60],{},"Qué lo arregla",[62,63,64,82,98,113],"tbody",{},[46,65,66,73,76,79],{},[67,68,69],"td",{},[70,71,72],"code",{},"NET::ERR_CERT_COMMON_NAME_INVALID",[67,74,75],{},"El certificado no es válido para tu dirección",[67,77,78],{},"Se emitió para otro nombre",[67,80,81],{},"Un certificado que incluya exactamente tu dirección",[46,83,84,89,92,95],{},[67,85,86],{},[70,87,88],{},"NET::ERR_CERT_AUTHORITY_INVALID",[67,90,91],{},"El certificado no es de confianza porque es autofirmado",[67,93,94],{},"Nadie responde por él salvo el propio servidor",[67,96,97],{},"Un certificado de una autoridad de verdad",[46,99,100,104,107,110],{},[67,101,102],{},[70,103,88],{},[67,105,106],{},"El emisor del certificado es desconocido",[67,108,109],{},"El navegador no puede conectarlo con ninguna autoridad de confianza",[67,111,112],{},"La cadena completa, de una autoridad reconocida",[46,114,115,120,123,126],{},[67,116,117],{},[70,118,119],{},"NET::ERR_CERT_DATE_INVALID",[67,121,122],{},"El certificado ha caducado",[67,124,125],{},"La fecha",[67,127,128],{},[20,129,130],{"href":22},"Un certificado nuevo",[10,132,133],{},"Chrome muestra el mismo código para la segunda y la tercera fila, y por eso\nmerece la pena abrir el propio certificado.",[10,135,136],{},"Si una sola persona te avisa y nadie más lo ve, pregúntale en qué red estaba. El\ncódigo fuente de Chrome cita una red wifi que manda a sus usuarios a una página\nde acceso como una de las causas del error de nombre. Ese se resuelve en cuanto\ninicia sesión en la red.",[26,138,140],{"id":139},"cómo-veo-lo-que-dice-el-certificado","¿Cómo veo lo que dice el certificado?",[10,142,143],{},"Ábrelo desde el aviso y lee dos campos: a quién se emitió y quién lo emitió.",[10,145,146,147,151,152,155],{},"En Chrome, haz clic en la indicación de alerta a la izquierda de la barra de\ndirecciones (",[148,149,150],"strong",{},"Not secure"," en un Chrome en inglés) y abre el certificado desde\nel panel que aparece. En Firefox, haz clic en ",[148,153,154],{},"Advanced"," en el aviso y luego en\nel enlace al certificado del sitio (así se llaman en un Firefox en inglés). Los\ndos navegadores llaman de forma distinta a los mismos campos:",[157,158,159,175],"ul",{},[160,161,162,163,166,167,170,171,174],"li",{},"El campo que dice a quién se emitió el certificado (",[148,164,165],{},"Issued To"," en un Chrome\nen inglés, ",[148,168,169],{},"Subject Name"," en Firefox) da el nombre para el que se hizo. La\nlista completa de nombres que cubre está bajo ",[148,172,173],{},"Subject Alternative Name",", y\nesa lista es lo que el navegador compara con la dirección.",[160,176,177,178,181,182,185],{},"El campo que dice quién lo emitió (",[148,179,180],{},"Issued By"," en Chrome, ",[148,183,184],{},"Issuer Name"," en\nFirefox) da la autoridad que lo firmó.",[10,187,188],{},"Cada una de las tres causas se lee distinto ahí:",[157,190,191,194,197],{},[160,192,193],{},"El certificado nombra otra dirección. Es la causa 1.",[160,195,196],{},"El titular y el emisor tienen el mismo nombre. Se firmó a sí mismo: es la\ncausa 2.",[160,198,199],{},"Nombra tu dirección, el emisor es una autoridad de la que has oído hablar, y el\nnavegador lo rechaza igualmente. Es la causa 3, la cadena.",[26,201,203],{"id":202},"causa-1-el-certificado-es-para-otra-dirección","Causa 1: el certificado es para otra dirección",[10,205,206],{},"El certificado es auténtico y está en fecha, y se emitió para otro nombre. Es la\nlicencia de otra tienda, colgada en tu escaparate.",[10,208,209],{},"Aparece de tres formas:",[157,211,212,218,232],{},[160,213,214,217],{},[148,215,216],{},"Tu dominio apunta a un hosting que todavía no tiene certificado para él."," El\nhosting responde con el certificado que tiene, emitido a un nombre suyo. La\ndocumentación de Lovable lo dice claramente: hasta que el certificado está\nlisto, el navegador muestra un aviso de seguridad en lugar de tu web.",[160,219,220,223,224,227,228,231],{},[148,221,222],{},"El certificado cubre una forma de escribir tu dirección y el visitante\nescribió la otra."," ",[70,225,226],{},"www.yourapp.com"," y ",[70,229,230],{},"yourapp.com"," son dos nombres para un\ncertificado, y cada uno tiene que estar en su lista.",[160,233,234,237],{},[148,235,236],{},"Una parte de tu DNS todavía apunta a un sitio que dejaste."," Un hosting\nantiguo, o la página de aparcamiento que mostraba tu registrador antes de que\nconectaras nada, responde en ese nombre con un certificado propio.",[239,240],"diagram",{"alt":241,"caption":242,"src":243},"Dos filas. En cada una, una barra de direcciones con yourapp.com está junto a una tarjeta de certificado que enumera los nombres que cubre. Arriba, la tarjeta solo incluye www.yourapp.com y la fila termina en una cruz. Abajo incluye los dos nombres y la fila termina en una marca de visto bueno.","Para un certificado, la dirección con www y la que va sin ella son dos nombres. La dirección de la barra tiene que estar en la lista.","\u002Fblog\u002Fcertificate-not-trusted\u002Fone-name-missing-1600x660.png",[10,245,246],{},"En Lovable y Vercel no compras ni instalas este certificado tú. El hosting emite\nuno por cada nombre que añades en sus ajustes de dominio, una vez que tu DNS\napunta ese nombre hacia él. La documentación de Lovable añade que su hosting no\nusa en absoluto un certificado comprado a tu registrador. Añade las dos formas,\napunta las dos al hosting y espera a que cada una aparezca como activa.",[26,248,250],{"id":249},"causa-2-el-certificado-se-firmó-a-sí-mismo","Causa 2: el certificado se firmó a sí mismo",[10,252,253],{},"Nadie responde por este certificado salvo el servidor que lo presenta. Es una\nlicencia que el tendero imprimió en casa.",[10,255,256],{},"Todos los navegadores rechazan uno en una web pública, y deben hacerlo. Un\ncomentario en el código fuente de Chrome da el motivo en una línea: un\ncertificado autofirmado no ofrece ninguna defensa frente a un atacante situado\nentre tu visitante y tu aplicación.",[10,258,259],{},"Te lo encuentras en servidores que alguien configuró a mano: un servidor\nalquilado, una herramienta autoalojada, un ajuste de prueba que salió a\nproducción con la aplicación. Un builder emite certificados de verdad para los\ndominios que le añades. Un certificado autofirmado en una aplicación alojada por\nun builder significa, por tanto, que algo distinto del builder está respondiendo\nen tu dirección. Comprueba adónde apunta tu DNS antes de cambiar nada más.",[10,261,262],{},"La solución es un certificado de una autoridad de verdad. Let's Encrypt los\nemite gratis, y es la autoridad que usa Vercel cuando emite el tuyo.",[26,264,266],{"id":265},"causa-3-nunca-se-envió-un-eslabón-de-la-cadena","Causa 3: nunca se envió un eslabón de la cadena",[10,268,269],{},"El certificado es para tu dirección y lo firmó una autoridad de verdad, pero el\nservidor lo envió sin el certificado intermedio, así que el navegador no puede\nconectarlo con nadie en quien confíe. La licencia la firmó una sucursal, y en el\nescaparate falta la carta de la central que responde por esa sucursal.",[10,271,272],{},"Mozilla llama a un certificado intermedio que falta uno de los problemas de\nconfiguración de servidores más comunes. Firefox descarga ahora por adelantado\nuna copia de cada certificado intermedio de confianza, para que sus usuarios\ndejen de encontrarse el error.",[10,274,275],{},"Eso es lo que hace que esta causa cueste verla: en tu portátil puede parecer que\ntodo va bien mientras a otra persona le falla. Un navegador que tiene su propia\ncopia del eslabón que falta rellena el hueco. Un software que solo usa lo que\nenvía tu servidor no tiene con qué rellenarlo. Nuestro escáner es de ese tipo de\nsoftware, y por eso puede marcar un certificado como no confiable mientras tu\npropio navegador muestra un candado.",[239,277],{"alt":278,"caption":279,"src":280},"Un servidor envía un certificado a dos visitantes. Entre el certificado y la autoridad de confianza debería haber un segundo certificado, y el servidor no lo ha enviado. El primer visitante tiene una copia del certificado que falta y recibe una marca de visto bueno. El segundo no tiene nada y recibe una cruz.","La misma cadena incompleta, enviada a dos visitantes. Solo el que ya tenía el eslabón que falta puede completarla.","\u002Fblog\u002Fcertificate-not-trusted\u002Fthe-missing-link-1600x700.png",[10,282,283,284,287,288,291,292,298],{},"En un builder la cadena se gestiona por ti. Falta en servidores configurados a\nmano, y ahí la solución es servir el certificado seguido del certificado\nintermedio, en un solo archivo. Si usas certbot de Let's Encrypt, ese archivo es\n",[70,285,286],{},"fullchain.pem",", y el error es apuntar tu servidor a ",[70,289,290],{},"cert.pem"," en su lugar. Para\ncomprobarlo desde fuera, ",[20,293,297],{"href":294,"rel":295},"https:\u002F\u002Fwww.ssllabs.com\u002Fssltest\u002F",[296],"nofollow","la prueba de servidor gratuita de SSL Labs","\nseñala un certificado intermedio que falta como un problema de la cadena.",[26,300,302],{"id":301},"el-caso-del-dominio-propio-paso-a-paso","El caso del dominio propio, paso a paso",[10,304,305],{},"Cuando conectas tu propio dominio a un builder, los visitantes ven este aviso\nhasta que el hosting tiene un certificado para tu nombre, y el aviso dice la\nverdad. Se acaba solo cuando se emite el certificado.",[10,307,308],{},"El orden, en Lovable:",[310,311,312,320,323,326],"ol",{},[160,313,314,315,227,317,319],{},"Añade el dominio en Lovable. Configura ",[70,316,230],{},[70,318,226],{}," y\nlos muestra por separado.",[160,321,322],{},"Cambia los registros DNS en tu registrador a los valores que te da Lovable.\nSegún Lovable, la mayoría de los cambios están activos en pocas horas, y la\npropagación puede tardar hasta 72.",[160,324,325],{},"Lovable verifica el dominio y emite el certificado. Vercel funciona igual:\ndemuestra a Let's Encrypt que el nombre es tuyo, automáticamente, siempre que\nel dominio apunte a Vercel.",[160,327,328,329,332],{},"Abre la web cuando el dominio aparezca como ",[148,330,331],{},"Live",", que es lo que aconseja\nla propia Lovable.",[239,334],{"alt":335,"caption":336,"src":337},"Una línea de tiempo. Una figura apunta un nombre hacia un hosting, y desde ese momento un tramo ámbar con un signo de aviso llega hasta un sello que marca la emisión del certificado. Después la línea pasa al color de acento, con un candado. Una marca más adelante lleva el número 72.","Entre apuntar tu dominio al hosting y la llegada del certificado, el aviso es correcto. Lovable te pide contactar con su soporte si sigue ahí después de 72 horas.","\u002Fblog\u002Fcertificate-not-trusted\u002Fthe-wait-is-the-warning-1600x560.png",[10,339,340],{},"Si el aviso sigue ahí después de 72 horas, Lovable te pide que contactes con su\nsoporte. Hay dos ajustes que conviene revisar antes de escribir:",[157,342,343,353],{},[160,344,345,348,349,352],{},[148,346,347],{},"Busca un registro CAA."," Es una entrada DNS que indica qué autoridades\npueden emitir certificados para tu dominio. Una que deja fuera a la autoridad\nde tu hosting bloquea el certificado, y un subdominio hereda los registros CAA\ndel dominio padre cuando no tiene los suyos.\n",[20,350,351],{"href":22},"El artículo sobre la caducidad"," se\nencuentra el mismo registro como motivo de que falle una renovación. Aquí\nimpide que llegue a emitirse el primer certificado.",[160,354,355,358],{},[148,356,357],{},"Busca un proxy delante."," Si tu DNS está en Cloudflare con la nube naranja\nactivada en los registros que te dio tu hosting, responde Cloudflare en lugar\nde tu hosting. Lovable dice que entonces no puede verificar el dominio ni\nemitir certificados para él, y tanto Lovable como Vercel dicen que pongas esos\nregistros en DNS only.",[26,360,362],{"id":361},"qué-encontramos-en-30879-aplicaciones","Qué encontramos en 30.879 aplicaciones",[10,364,365],{},"Ocho tenían un certificado en el que ningún navegador confiaría, y todas estaban\nen un dominio que su dueño había conectado.",[10,367,368],{},"En agosto de 2026 nuestro escaneo leyó el certificado de 30.879 aplicaciones en\nproducción: 29.927 en el subdominio propio de un builder y 952 en un dominio\npropio. Los ocho certificados no confiables estaban entre las 952, algo menos de\nuno de cada cien. Ninguna de las aplicaciones en el subdominio de un builder\ntenía uno, lo que encaja con todo lo anterior. En la dirección propia del\nbuilder, el nombre y el certificado son del builder.",[10,370,371,372,375],{},"Nuestro hallazgo registra que el certificado falló, pero no cuál de las tres\ncausas fue, así que no podemos decirte cómo se reparten las ocho. Los\ncertificados caducados o a punto de caducar del mismo escaneo se cuentan en\n",[20,373,374],{"href":22},"el artículo sobre la caducidad",".",[10,377,378,379,383],{},"Para comprobar tu propia aplicación, ",[20,380,382],{"href":381},"\u002Fsecurity-scanner","nuestro escaneo gratuito","\nlee desde fuera el certificado que envía tu servidor y nombra este hallazgo\ncuando lo ve. Tarda unos 20 segundos y no necesita cuenta.",[26,385,387],{"id":386},"enterarte-la-próxima-vez-que-algo-cambie","Enterarte la próxima vez que algo cambie",[10,389,390],{},"Un certificado pasa de confiable a rechazado cuando cambia algo a su alrededor:\nun dominio nuevo, una mudanza de DNS, un proxy activado. La comprobación que\nimporta es la que se hace después del cambio.",[10,392,393,398],{},[148,394,395],{},[20,396,397],{"href":381},"Escanea tu aplicación gratis"," para ver lo que recibe hoy\nel navegador de un visitante.",[157,400,401,404,407],{},[160,402,403],{},"Lee desde fuera el certificado que envía tu servidor, junto con otras ocho\ncomprobaciones.",[160,405,406],{},"Nombra el hallazgo cuando el certificado no es de confianza, y cuando ha\ncaducado o está a punto de hacerlo.",[160,408,409],{},"Unos 20 segundos, y sin cuenta.",[10,411,412,418],{},[148,413,414],{},[20,415,417],{"href":416},"\u002Fwebsite-monitoring","Reeve Monitor"," para enterarte poco después del cambio.",[157,420,421,424,427],{},[160,422,423],{},"Comprueba tu aplicación cada 60 segundos, y un certificado en el que no puede\nconfiar cuenta como una caída de tu aplicación. Te avisa, por tanto, como con\ncualquier otra caída.",[160,425,426],{},"Repite las nueve comprobaciones cada hora y te envía un correo cuando baja tu\nnota.",[160,428,429],{},"Cubre hasta tres aplicaciones.",[26,431,433],{"id":432},"qué-hacer-ahora-mismo","Qué hacer ahora mismo",[435,436,437],"key-takeaways",{},[157,438,439,442,445,453,456],{},[160,440,441],{},"Lee el código bajo el aviso antes de renovar nada. Un error de fecha necesita un certificado nuevo. Un error de nombre o de autoridad necesita otra cosa.",[160,443,444],{},"Abre el certificado y compara el nombre para el que se emitió con la dirección de la barra, y con el nombre de quien lo emitió.",[160,446,447,448,227,450,452],{},"En un builder, añade ",[70,449,230],{},[70,451,226],{}," en sus ajustes de dominio y apunta los dos hacia él.",[160,454,455],{},"Si un dominio nuevo sigue mostrando el aviso después de 72 horas, busca un registro CAA o un proxy delante del hosting antes de contactar con soporte.",[160,457,458],{},"En un servidor que gestionas tú, sirve la cadena completa y compruébala desde fuera con SSL Labs.",[10,460,461,462,466],{},"Cuando el aviso ha desaparecido y la aplicación sigue sin cargar, la siguiente\npregunta es si es tu aplicación o la plataforma que hay debajo, y\n",[20,463,465],{"href":464},"\u002Fblog\u002Fis-supabase-down-or-your-app","¿se ha caído Supabase o es tu aplicación?","\nexplica cómo distinguirlo.",{"title":468,"searchDepth":469,"depth":469,"links":470},"",3,[471,473,474,475,476,477,478,479,480],{"id":28,"depth":472,"text":29},2,{"id":139,"depth":472,"text":140},{"id":202,"depth":472,"text":203},{"id":249,"depth":472,"text":250},{"id":265,"depth":472,"text":266},{"id":301,"depth":472,"text":302},{"id":361,"depth":472,"text":362},{"id":386,"depth":472,"text":387},{"id":432,"depth":472,"text":433},"Fundamentos de seguridad","\u002Fblog\u002Fcertificate-not-trusted\u002Fcover-1200x630.png","Tarjeta de certificado con sello y fecha en color de acento, bajo una barra de direcciones con un nombre más largo que el de la tarjeta.","¿Certificado no confiable aunque la fecha está bien? Nombra otra dirección, se firmó a sí mismo o a su cadena le falta un eslabón. Cómo saber cuál.",false,"md",[488,491,494,497,500],{"q":489,"a":490},"¿Por qué mi web dice que la conexión no es privada si mi certificado no ha caducado?","Porque la fecha es solo una de las tres cosas que comprueba un navegador, y las otras dos fallan por su cuenta. El certificado también tiene que nombrar exactamente la dirección que escribió el visitante, y estar firmado por una autoridad en la que el navegador confía, con cada certificado intermedio enviado junto a él. Un certificado que falla cualquiera de las dos comprobaciones recibe el mismo aviso a pantalla completa que uno caducado, y renovarlo no cambia nada.",{"q":492,"a":493},"¿Qué es un error de nombre del certificado?","Un certificado emitido para una dirección y presentado en otra. Chrome lo indica como NET::ERR_CERT_COMMON_NAME_INVALID y Firefox dice que el certificado no es válido para tu dirección. El certificado en sí suele ser auténtico y estar en fecha. Simplemente pertenece a otro nombre, a menudo el de tu proveedor de hosting, y eso es lo que un hosting presenta en tu dominio antes de haber emitido uno para ti.",{"q":495,"a":496},"¿Por qué funciona con www y no el dominio sin www?","Porque para un certificado son dos nombres distintos. O el certificado solo incluye uno de ellos, o el DNS del otro todavía apunta a otro sitio, como la página de aparcamiento de tu registrador o un hosting antiguo, que responde con un certificado propio. Lovable conecta los dos y los muestra por separado, así que comprueba que cada uno aparece como activo.",{"q":498,"a":499},"¿Cuánto tarda el certificado de un dominio propio?","Según Lovable, la configuración de un dominio suele terminar en pocos minutos pero puede llevar varias horas, los cambios de DNS pueden tardar hasta 72 horas en propagarse, y conviene contactar con su soporte si el certificado no se ha emitido tras 72 horas. Hasta que se emite, los visitantes ven un aviso de seguridad en lugar de tu web.",{"q":501,"a":502},"¿Un certificado autofirmado está bien alguna vez?","En tu propio ordenador, para desarrollar, sí. En una web que visita el público, no. El navegador de cada visitante lo rechaza, y un comentario en el código fuente de Chrome señala que un certificado autofirmado no ofrece ninguna defensa frente a un atacante situado entre el visitante y la web.","\u002Fblog\u002Fcertificate-not-trusted\u002Fcard-800x500.png",[505,506,507,508,509,510,511],"certificado no confiable","certificado ssl no confiable navegador","la conexión no es privada dominio propio","el nombre del certificado no coincide","certificado autofirmado aviso web","net::err_cert_common_name_invalid","net::err_cert_authority_invalid",{},true,"\u002Fblog\u002Fcertificate-not-trusted","2026-10-26",{"title":5,"description":484},"blog\u002Fcertificate-not-trusted",[519,520,521],"Un certificado no confiable para los navegadores puede estar perfectamente en fecha. Se rechaza porque nombra otra dirección, porque se firmó a sí mismo o porque llegó sin el certificado que responde por él.","La pantalla de aviso es la misma que recibe un certificado caducado, y renovarlo no arregla ninguna de las tres causas. El código que aparece bajo el aviso te dice cuál tienes.","En Lovable y Vercel, un dominio propio muestra este aviso hasta que se emite su certificado. Esa espera es normal. Un aviso que dura más significa que algo está frenando el certificado.","RxaleIbjR6AG2ATILIaiGlGPNlXSyfV2s9XSAFsqIBo",[524,530,536,542,548,554,560,566,572,578,584,591,597,603,609,610,616,622,628,634,640,646,652,658,664,670,676,682,688,694,700,706,712,718,724,730,736,742,748,754,759,765,771,777,783,789,794,800,806,812,817,823,829,835,841,847,853,859,865,871,877,883,889,895,901,907,913,919,925,931,937,943,949,955,961,967,973,979,985,991,997,1003,1009,1015,1020,1026,1032,1038,1043,1049],{"path":525,"title":526,"description":527,"published":528,"category":481,"image":529,"draft":485},"\u002Fblog\u002Fmax-client-connections-reached","Supabase \"max client connections reached\", explicado","Supabase \"max client connections reached\": el pooler no tiene sitio para un cliente más. El puerto de tu cadena de conexión decide el límite.","2026-11-09","\u002Fblog\u002Fmax-client-connections-reached\u002Fcard-800x500.png",{"path":531,"title":532,"description":533,"published":534,"category":481,"image":535,"draft":485},"\u002Fblog\u002Funsupported-provider-provider-is-not-enabled","Error de Supabase: \"Unsupported provider: provider is not enabled\"","\"Unsupported provider: provider is not enabled\": Google está desactivado en tu proyecto Supabase. Cómo activarlo y arreglar redirect_uri_mismatch.","2026-11-08","\u002Fblog\u002Funsupported-provider-provider-is-not-enabled\u002Fcard-800x500.png",{"path":537,"title":538,"description":539,"published":540,"category":481,"image":541,"draft":485},"\u002Fblog\u002Fviolates-foreign-key-constraint","Error de Supabase \"violates foreign key constraint\" al insertar","Supabase \"insert or update on table violates foreign key constraint\": tu fila apunta a una fila que no existe. Cuál, por qué, y cómo arreglarlo.","2026-11-07","\u002Fblog\u002Fviolates-foreign-key-constraint\u002Fcard-800x500.png",{"path":543,"title":544,"description":545,"published":546,"category":481,"image":547,"draft":485},"\u002Fblog\u002Fnull-value-violates-not-null-constraint","Error de Supabase \"null value in column violates not-null constraint\"","Supabase \"null value in column violates not-null constraint\": una columna obligatoria llegó vacía. De dónde vino el null, y cómo arreglarlo.","2026-11-06","\u002Fblog\u002Fnull-value-violates-not-null-constraint\u002Fcard-800x500.png",{"path":549,"title":550,"description":551,"published":552,"category":481,"image":553,"draft":485},"\u002Fblog\u002Fauth-session-missing","Supabase \"Auth session missing!\": adónde fue la sesión","\"Auth session missing!\" es supabase-js sin encontrar ninguna sesión iniciada y sin llegar a preguntar a Supabase. Adónde fue la sesión, y el arreglo.","2026-11-05","\u002Fblog\u002Fauth-session-missing\u002Fcard-800x500.png",{"path":555,"title":556,"description":557,"published":558,"category":481,"image":559,"draft":485},"\u002Fblog\u002Finvalid-claim-missing-sub-claim","Supabase \"invalid claim: missing sub claim\": no hay nadie conectado","\"invalid claim: missing sub claim\": Supabase Auth recibió un token auténtico sin ningún usuario, la clave del proyecto en lugar de una sesión.","2026-11-04","\u002Fblog\u002Finvalid-claim-missing-sub-claim\u002Fcard-800x500.png",{"path":561,"title":562,"description":563,"published":564,"category":481,"image":565,"draft":485},"\u002Fblog\u002Ffailed-to-send-a-request-to-the-edge-function","\"Failed to send a request to the Edge Function\": la causa real","\"Failed to send a request to the Edge Function\": el navegador no recibió una respuesta legible. Su consola dice por qué y si tu función se ejecutó.","2026-11-03","\u002Fblog\u002Ffailed-to-send-a-request-to-the-edge-function\u002Fcard-800x500.png",{"path":567,"title":568,"description":569,"published":570,"category":481,"image":571,"draft":485},"\u002Fblog\u002Fsupabase-auth-redirects-to-localhost","Por qué los enlaces de email de Supabase redirigen a localhost:3000","Si Supabase redirige a localhost:3000, la Site URL nunca se cambió o tu dirección falta en Redirect URLs. La solución, y el comodín que debes evitar.","2026-11-02","\u002Fblog\u002Fsupabase-auth-redirects-to-localhost\u002Fcard-800x500.png",{"path":573,"title":574,"description":575,"published":576,"category":481,"image":577,"draft":485},"\u002Fblog\u002Femail-link-is-invalid-or-has-expired","Supabase \"Email link is invalid or has expired\" con un enlace nuevo","Con un enlace enviado hace un minuto, \"Email link is invalid or has expired\" en Supabase suele indicar que un filtro de correo lo usó antes. Cómo arreglarlo.","2026-11-01","\u002Fblog\u002Femail-link-is-invalid-or-has-expired\u002Fcard-800x500.png",{"path":579,"title":580,"description":581,"published":582,"category":481,"image":583,"draft":485},"\u002Fblog\u002Fcanceling-statement-due-to-statement-timeout","Supabase \"canceling statement due to statement timeout\", explicado","Supabase \"canceling statement due to statement timeout\": una consulta superó el límite de su rol, 3 segundos para un visitante. Revisa antes la política RLS.","2026-10-31","\u002Fblog\u002Fcanceling-statement-due-to-statement-timeout\u002Fcard-800x500.png",{"path":585,"title":586,"description":587,"published":588,"category":589,"image":590,"draft":485},"\u002Fblog\u002Fdatabase-error-deleting-user","\"Database error deleting user\" en Supabase, y qué se va con él","\"Database error deleting user\" en Supabase: tu base de datos rechazó el borrado. La causa está en tus logs y el arreglo decide qué más se borra.","2026-10-30","Backups","\u002Fblog\u002Fdatabase-error-deleting-user\u002Fcard-800x500.png",{"path":592,"title":593,"description":594,"published":595,"category":481,"image":596,"draft":485},"\u002Fblog\u002Fstripe-webhook-no-signatures-found","\"No signatures found matching the expected signature\" en Supabase","¿Tu webhook de Stripe en una Edge Function de Supabase dice \"No signatures found matching the expected signature\"? Tiene dos causas. Sigue verificando.","2026-10-29","\u002Fblog\u002Fstripe-webhook-no-signatures-found\u002Fcard-800x500.png",{"path":598,"title":599,"description":600,"published":601,"category":481,"image":602,"draft":485},"\u002Fblog\u002Fsupabase-invalid-login","\"Invalid login credentials\" en Supabase: las tres causas","Supabase dice \"Invalid login credentials\" ante una contraseña errónea, un email desconocido y una cuenta de Google. Cómo saber cuál es.","2026-10-28","\u002Fblog\u002Fsupabase-invalid-login\u002Fcard-800x500.png",{"path":604,"title":605,"description":606,"published":607,"category":481,"image":608,"draft":485},"\u002Fblog\u002Fedge-function-returned-a-non-2xx-status-code","\"Edge Function returned a non-2xx status code\": el error real","\"Edge Function returned a non-2xx status code\" significa que tu función de Supabase respondió con un error. Aquí ves dónde leer el real.","2026-10-27","\u002Fblog\u002Fedge-function-returned-a-non-2xx-status-code\u002Fcard-800x500.png",{"path":514,"title":5,"description":484,"published":515,"category":481,"image":503,"draft":485},{"path":611,"title":612,"description":613,"published":614,"category":481,"image":615,"draft":485},"\u002Fblog\u002Finvalid-input-syntax-for-type-uuid","Supabase \"invalid input syntax for type uuid\": lee las comillas","Supabase \"invalid input syntax for type uuid\" significa que tu app envió algo que no es un id. Lee las comillas, frena la consulta, conserva la columna.","2026-10-25","\u002Fblog\u002Finvalid-input-syntax-for-type-uuid\u002Fcard-800x500.png",{"path":617,"title":618,"description":619,"published":620,"category":481,"image":621,"draft":485},"\u002Fblog\u002Fduplicate-key-value-violates-unique-constraint","Supabase \"duplicate key value violates unique constraint\", explicado","Supabase \"duplicate key value violates unique constraint\": el valor ya está ocupado. Encuentra la columna, elige un arreglo y aparta el valor de la pantalla.","2026-10-24","\u002Fblog\u002Fduplicate-key-value-violates-unique-constraint\u002Fcard-800x500.png",{"path":623,"title":624,"description":625,"published":626,"category":481,"image":627,"draft":485},"\u002Fblog\u002Fsupabase-relation-does-not-exist","Supabase \"relation does not exist\" aunque la tabla está ahí","Supabase \"relation does not exist\" o PGRST205: ninguna tabla tiene ese nombre en ese esquema. Cuatro comprobaciones, y lo que abre exponer un esquema.","2026-10-23","\u002Fblog\u002Fsupabase-relation-does-not-exist\u002Fcard-800x500.png",{"path":629,"title":630,"description":631,"published":632,"category":481,"image":633,"draft":485},"\u002Fblog\u002Fsupabase-function-not-found","Supabase PGRST202: \"Could not find the function in the schema cache\"","Supabase \"Could not find the function in the schema cache\" muestra los nombres de argumentos que envió tu app. Compáralos con la función.","2026-10-22","\u002Fblog\u002Fsupabase-function-not-found\u002Fcard-800x500.png",{"path":635,"title":636,"description":637,"published":638,"category":481,"image":639,"draft":485},"\u002Fblog\u002Fsupabase-schema-cache-column-error","Supabase PGRST204: \"Could not find the column in the schema cache\"","Supabase \"Could not find the column in the schema cache\" suele ser un nombre que no coincide. Cuatro comprobaciones y la línea que recarga.","2026-10-21","\u002Fblog\u002Fsupabase-schema-cache-column-error\u002Fcard-800x500.png",{"path":641,"title":642,"description":643,"published":644,"category":481,"image":645,"draft":485},"\u002Fblog\u002Fsupabase-email-rate-limit-exceeded","Supabase \"Email Rate Limit Exceeded\": dos límites, un solo código","Supabase \"Email Rate Limit Exceeded\" limita cada email que envía tu proyecto: 2 por hora con el remitente integrado. Qué cuenta y cómo subirlo.","2026-10-20","\u002Fblog\u002Fsupabase-email-rate-limit-exceeded\u002Fcard-800x500.png",{"path":647,"title":648,"description":649,"published":650,"category":481,"image":651,"draft":485},"\u002Fblog\u002Fsupabase-users-logged-out","Supabase \"Invalid Refresh Token: Refresh Token Not Found\": 3 causas","Supabase \"Invalid Refresh Token: Refresh Token Not Found\" cierra la sesión de tus usuarios. Tres causas, y cómo las separa el log de Auth.","2026-10-19","\u002Fblog\u002Fsupabase-users-logged-out\u002Fcard-800x500.png",{"path":653,"title":654,"description":655,"published":656,"category":481,"image":657,"draft":485},"\u002Fblog\u002Fpermission-denied-for-schema-public","Supabase \"permission denied for schema public\": tres causas","Supabase \"permission denied for schema public\" es un grant que falta en el esquema. Qué lo quitó y la línea que lo devuelve.","2026-10-18","\u002Fblog\u002Fpermission-denied-for-schema-public\u002Fcard-800x500.png",{"path":659,"title":660,"description":661,"published":662,"category":481,"image":663,"draft":485},"\u002Fblog\u002Fsupabase-bucket-not-found","Supabase \"Bucket not found\": las tres cosas que significa","Supabase \"Bucket not found\" es una de tres cosas: un enlace público a un bucket privado, un nombre que no coincide exactamente o el proyecto equivocado.","2026-10-17","\u002Fblog\u002Fsupabase-bucket-not-found\u002Fcard-800x500.png",{"path":665,"title":666,"description":667,"published":668,"category":481,"image":669,"draft":485},"\u002Fblog\u002Fsupabase-invalid-jwt","Supabase invalid JWT: ¿qué clave dejó de funcionar?","Un error Supabase invalid JWT es PGRST301: un token firmado no pasó la verificación. En un proyecto nuevo se trata de la sesión, no de la clave de API.","2026-10-16","\u002Fblog\u002Fsupabase-invalid-jwt\u002Fcard-800x500.png",{"path":671,"title":672,"description":673,"published":674,"category":481,"image":675,"draft":485},"\u002Fblog\u002Fsupabase-single-row-error","Supabase \"multiple (or no) rows returned\" casi siempre es ninguna","Supabase devuelve PGRST116, \"JSON object requested, multiple (or no) rows returned\", cuando tu consulta no encontró nada. Una fila oculta parece ausente.","2026-10-15","\u002Fblog\u002Fsupabase-single-row-error\u002Fcard-800x500.png",{"path":677,"title":678,"description":679,"published":680,"category":481,"image":681,"draft":485},"\u002Fblog\u002Fdatabase-error-saving-new-user","\"Database error saving new user\" en Supabase: dónde mirar","\"Database error saving new user\" significa que algo unido a tu registro de Supabase falló y se deshizo entero. El error real está en tus logs.","2026-10-14","\u002Fblog\u002Fdatabase-error-saving-new-user\u002Fcard-800x500.png",{"path":683,"title":684,"description":685,"published":686,"category":481,"image":687,"draft":485},"\u002Fblog\u002Fwhat-is-supabase","¿Qué es Supabase? La base de datos que eligió tu builder","Qué es Supabase: la base de datos, el login y el almacenamiento de archivos de tu app. Supabase lleva los servidores; las reglas sobre tus filas son tuyas.","2026-10-13","\u002Fblog\u002Fwhat-is-supabase\u002Fcard-800x500.png",{"path":689,"title":690,"description":691,"published":692,"category":481,"image":693,"draft":485},"\u002Fblog\u002Faws-access-key-exposed-in-frontend","Una clave AWS expuesta en tu frontend no es como una clave OpenAI","Una clave de acceso de AWS expuesta en tu frontend lee y escribe tu almacenamiento. La solución suele ser una presigned URL, no una clave nueva.","2026-10-12","\u002Fblog\u002Faws-access-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":695,"title":696,"description":697,"published":698,"category":481,"image":699,"draft":485},"\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":701,"title":702,"description":703,"published":704,"category":481,"image":705,"draft":485},"\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":707,"title":708,"description":709,"published":710,"category":481,"image":711,"draft":485},"\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":713,"title":714,"description":715,"published":716,"category":481,"image":717,"draft":485},"\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":719,"title":720,"description":721,"published":722,"category":481,"image":723,"draft":485},"\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":725,"title":726,"description":727,"published":728,"category":481,"image":729,"draft":485},"\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":731,"title":732,"description":733,"published":734,"category":481,"image":735,"draft":485},"\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.","2026-10-05","\u002Fblog\u002Fmove-a-secret-to-an-edge-function\u002Fcard-800x500.png",{"path":737,"title":738,"description":739,"published":740,"category":481,"image":741,"draft":485},"\u002Fblog\u002Fenv-file-exposed-on-your-server","¿Tu archivo .env está expuesto? Las doce rutas a revisar","¿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.","2026-10-04","\u002Fblog\u002Fenv-file-exposed-on-your-server\u002Fcard-800x500.png",{"path":743,"title":744,"description":745,"published":746,"category":481,"image":747,"draft":485},"\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":749,"title":750,"description":751,"published":752,"category":481,"image":753,"draft":485},"\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":464,"title":755,"description":756,"published":757,"category":481,"image":758,"draft":485},"¿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":760,"title":761,"description":762,"published":763,"category":481,"image":764,"draft":485},"\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":766,"title":767,"description":768,"published":769,"category":481,"image":770,"draft":485},"\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":772,"title":773,"description":774,"published":775,"category":589,"image":776,"draft":485},"\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","\u002Fblog\u002Ftest-your-supabase-backup\u002Fcard-800x500.png",{"path":778,"title":779,"description":780,"published":781,"category":589,"image":782,"draft":485},"\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":784,"title":785,"description":786,"published":787,"category":589,"image":788,"draft":485},"\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":790,"title":791,"description":792,"published":787,"category":481,"image":793,"draft":485},"\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":795,"title":796,"description":797,"published":798,"category":481,"image":799,"draft":485},"\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":801,"title":802,"description":803,"published":804,"category":481,"image":805,"draft":485},"\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":807,"title":808,"description":809,"published":810,"category":589,"image":811,"draft":485},"\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":22,"title":813,"description":814,"published":815,"category":481,"image":816,"draft":485},"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":818,"title":819,"description":820,"published":821,"category":481,"image":822,"draft":485},"\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":824,"title":825,"description":826,"published":827,"category":481,"image":828,"draft":485},"\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":830,"title":831,"description":832,"published":833,"category":481,"image":834,"draft":485},"\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":836,"title":837,"description":838,"published":839,"category":481,"image":840,"draft":485},"\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":842,"title":843,"description":844,"published":845,"category":481,"image":846,"draft":485},"\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":848,"title":849,"description":850,"published":851,"category":481,"image":852,"draft":485},"\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":854,"title":855,"description":856,"published":857,"category":481,"image":858,"draft":485},"\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":860,"title":861,"description":862,"published":863,"category":589,"image":864,"draft":485},"\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":866,"title":867,"description":868,"published":869,"category":589,"image":870,"draft":485},"\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":872,"title":873,"description":874,"published":875,"category":589,"image":876,"draft":485},"\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":878,"title":879,"description":880,"published":881,"category":481,"image":882,"draft":485},"\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":884,"title":885,"description":886,"published":887,"category":481,"image":888,"draft":485},"\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":890,"title":891,"description":892,"published":893,"category":481,"image":894,"draft":485},"\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":896,"title":897,"description":898,"published":899,"category":481,"image":900,"draft":485},"\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":902,"title":903,"description":904,"published":905,"category":481,"image":906,"draft":485},"\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. Ocho herramientas, con precios.","2026-09-07","\u002Fblog\u002Fvibe-coding-security-scanners-compared\u002Fcard-800x500.png",{"path":908,"title":909,"description":910,"published":911,"category":481,"image":912,"draft":485},"\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":914,"title":915,"description":916,"published":917,"category":481,"image":918,"draft":485},"\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":920,"title":921,"description":922,"published":923,"category":481,"image":924,"draft":485},"\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":926,"title":927,"description":928,"published":929,"category":481,"image":930,"draft":485},"\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":932,"title":933,"description":934,"published":935,"category":481,"image":936,"draft":485},"\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":938,"title":939,"description":940,"published":941,"category":589,"image":942,"draft":485},"\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":944,"title":945,"description":946,"published":947,"category":481,"image":948,"draft":485},"\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":950,"title":951,"description":952,"published":953,"category":589,"image":954,"draft":485},"\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":956,"title":957,"description":958,"published":959,"category":481,"image":960,"draft":485},"\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":962,"title":963,"description":964,"published":965,"category":481,"image":966,"draft":485},"\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":968,"title":969,"description":970,"published":971,"category":481,"image":972,"draft":485},"\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":974,"title":975,"description":976,"published":977,"category":481,"image":978,"draft":485},"\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":980,"title":981,"description":982,"published":983,"category":589,"image":984,"draft":485},"\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":986,"title":987,"description":988,"published":989,"category":589,"image":990,"draft":485},"\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":992,"title":993,"description":994,"published":995,"category":481,"image":996,"draft":485},"\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":998,"title":999,"description":1000,"published":1001,"category":481,"image":1002,"draft":485},"\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":1004,"title":1005,"description":1006,"published":1007,"category":589,"image":1008,"draft":485},"\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":1010,"title":1011,"description":1012,"published":1013,"category":481,"image":1014,"draft":485},"\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":1016,"title":1017,"description":1018,"published":1013,"category":481,"image":1019,"draft":485},"\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":1021,"title":1022,"description":1023,"published":1024,"category":481,"image":1025,"draft":485},"\u002Fblog\u002Fsupabase-new-api-keys","Supabase publishable key: ¿es la misma que la anon key?","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":1027,"title":1028,"description":1029,"published":1030,"category":589,"image":1031,"draft":485},"\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":1033,"title":1034,"description":1035,"published":1036,"category":481,"image":1037,"draft":485},"\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":1039,"title":1040,"description":1041,"published":1036,"category":589,"image":1042,"draft":485},"\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":1044,"title":1045,"description":1046,"published":1047,"category":589,"image":1048,"draft":485},"\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":1050,"title":1051,"description":1052,"published":1047,"category":481,"image":1053,"draft":485},"\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",1794213645088]