Fundamentos de seguridad
¿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.
En resumen
- Una clave de API de Google expuesta en tu frontend casi siempre está bien, porque una clave de Google es un identificador de facturación y no una contraseña.
- Lo que la hace segura es una restricción de referente HTTP: un ajuste que le dice a Google que la clave solo funciona desde tu propio sitio web.
- Es gratis, lleva unos cinco minutos y es lo único que merece la pena hacer hoy.
- Un archivo de cuenta de servicio de Google en tu app es el caso distinto y urgente. Eso sí son credenciales reales.
Abre tu app en el navegador, mira el código fuente de la página y busca AIza.
Si aparece una cadena de cuarenta caracteres, probablemente alguien ya te ha
dicho que está «expuesta», y probablemente no te dijo qué hacer después.
Aquí está la parte que la mayoría de los consejos sobre esto se equivocan: una clave de API de Google en tu frontend no es el mismo tipo de problema que una clave secreta de Stripe en tu frontend, y el arreglo no consiste en esconderla. Tratar las dos igual lleva o bien a asustarse por tu mapa o, peor, a acostumbrarse a encogerse de hombros ante la palabra «expuesta» justo antes del día en que importa.
Entre el 12 y el 14 de agosto de 2026 pasamos las mismas nueve comprobaciones externas a 30.998 apps en funcionamiento creadas con Lovable, Bolt, v0, Replit y Base44. En 1.142 de ellas apareció una clave de API de Google. En tres apareció una clave secreta de Stripe. Los números completos están en nuestro informe de escaneo.
¿Es malo que mi clave de API de Google esté expuesta en el frontend?
Casi nunca. Depende por completo de si la clave está restringida.
Una clave de API de Google no es una contraseña. Se parece más a un número de cuenta: le dice a Google qué proyecto facturar y de qué cuota descontar. Por sí sola no dice nada sobre quién hace la petición.
Por eso puede vivir en tu página. El mapa lo dibuja el navegador de tu visitante, así que el navegador es quien tiene que enviar ese número de cuenta a Google. No existe una versión de esto en la que el mapa cargue y el número quede oculto.
La protección viene de un segundo ajuste, guardado del lado de Google, que dice desde qué sitios web puede usarse el número. Google lo llama restricción de referente HTTP. Con él puesto, la clave impresa en tu página funciona en tu sitio y devuelve un error en cualquier otro.
Por qué tu app envía la clave
Porque la petición sale del navegador de tu visitante, no de tu servidor.
Cuando alguien carga una página con un mapa, ese navegador habla directamente con
maps.googleapis.com. Tiene que decir a qué proyecto de Google pertenece la
petición, y ese identificador tiene que estar en la página, porque la página es
desde donde se hace la petición.
Google lo sabe. Por eso la restricción existe como control aparte: el identificador iba a ser público de todas formas, así que lo que decide quién puede usarlo vive en un sitio al que el público no llega.
Cómo restringir una clave de API de Google
Es gratis, son unos cinco minutos y no necesitas tocar el código de tu app. En la consola de Google Cloud:
- Ve a APIs y servicios → Credenciales y haz clic en la clave que encontraste.
- En Restricciones de aplicación, elige Sitios web.
- Añade tu dominio. Para un sitio en
yourapp.com, añadehttps://yourapp.com/*. Añade también tu dominio de vista previa o de pruebas, si tienes uno, y acuérdate de la dirección.lovable.appo.vercel.appen la que se publicó tu app antes de conectarle un dominio propio. - En Restricciones de API, elige Restringir clave y marca solo las APIs que tu app llama de verdad. Un mapa con búsqueda de lugares necesita la API de JavaScript de Maps y la API de Places, y nada más.
- Guarda, espera unos minutos, luego carga tu propio sitio y comprueba que el mapa se sigue dibujando.
Si el paso 3 está mal, te enteras al momento y a la vista: el mapa falla con
RefererNotAllowedMapError en la consola del navegador, que nombra el problema
exacto. Añade el dominio que falta y vuelve a funcionar. Es un cambio reversible,
y por eso merece la pena hacerlo antes de terminar de leer sobre él.
Una cosa que no hay que hacer: la propia guía de resolución de problemas de Google dice que las restricciones por dirección IP son para claves de servidor y no sirven para una clave que usa un navegador. Si restringes por IP una clave del frontend, tu app se rompe para todos los visitantes.
Si prefieres ver qué claves está enviando tu app antes de ir una por una, nuestro escaneo gratuito lee tu sitio en vivo desde fuera y te dice lo que encuentra. Tarda unos 20 segundos y no necesita cuenta: escanea tu app.
Qué credenciales de Google van en un navegador
| Credencial | Qué aspecto tiene | ¿En tu frontend? | Qué la protege de verdad |
|---|---|---|---|
| Clave de navegador de Maps o Places | AIza… | Va aquí | La restricción de referente, más un tope de cuota |
| Clave de configuración web de Firebase | AIza… | Va aquí | Las reglas de seguridad de Firebase y App Check |
| Una clave que usas desde tu servidor | AIza… | Nunca | Nada, una vez es pública. Déjala en el servidor |
| Cuenta de servicio | un archivo JSON que contiene "private_key" | Nunca | Nada. Esto sí son credenciales reales |
Las tres primeras filas son la misma cadena. Una clave de API de Google no lleva escrito por delante para qué sirve, así que la pregunta nunca es «qué aspecto tiene esta clave» sino «qué puede hacer esta clave», y esa respuesta vive en la consola y no en tu código.
La clave de Firebase está pensada para ser pública
Esta es la fila por la que más preguntan, y la propia documentación de Firebase la responde con claridad: las claves de API de los servicios de Firebase pueden ir en el código o en archivos de configuración, porque no controlan el acceso a nada. De eso deciden las reglas de seguridad de Firebase y App Check.
Si te suena, es el mismo arreglo que usa Supabase. La clave publicable identifica el proyecto, y las reglas que hay detrás deciden fila por fila quién puede leer qué. En ambos casos la clave es segura solo gracias a esas reglas, así que las reglas son lo que hay que ir a mirar: activarlas no es lo mismo que estar protegido.
Qué pasa de verdad cuando se filtra una clave sin restringir
Una factura, una caída o las dos. No una fuga de datos.
Los rastreadores automáticos recorren páginas públicas recogiendo cadenas AIza,
y una clave sin restringir funciona desde cualquier sitio, así que la tuya acaba
sirviendo teselas de mapa y búsquedas de lugares para el proyecto de otro. Google
lo dice directamente en su propia documentación de primeros pasos: la razón para
poner restricciones es evitar el robo de cuota.
Normalmente te enteras de una de dos maneras. La factura es mayor que la del mes pasado sin un motivo que puedas señalar, o los mapas de tu app dejan de dibujarse a mitad de mes porque el proyecto ha agotado su cuota y ahora cada visitante ve un rectángulo gris.
Ambas cosas tienen arreglo. Ninguna expone los datos de tus usuarios, porque una clave de Maps no puede leer tu base de datos. Esa es la diferencia honesta entre este hallazgo y una clave de base de datos filtrada, y es la razón por la que nuestro escáner reporta una clave de API de Google como algo que revisar y no como una emergencia.
La única credencial de Google que sí se comporta como una emergencia es una
cuenta de servicio. Si tu app está enviando un archivo JSON con
"type": "service_account" y un bloque "private_key" dentro, eso son
credenciales reales con permisos reales sobre tu proyecto en la nube. Borra la
clave en la consola y luego mira a qué podía llegar.
Qué hacer ahora mismo
Qué hacer
- Busca
AIzaen el código fuente de tu sitio en vivo. Cada coincidencia es una clave de la que responder. - Restringe cada una en la consola de Google Cloud: Sitios web en las restricciones de aplicación, tu dominio, y solo las APIs que usas. Gratis, unos cinco minutos, sin tocar código.
- Ponle también un tope de cuota diaria a la clave mientras estás ahí. La restricción reduce el tráfico; un tope limita lo que todo eso puede costar.
- Deja tu clave de configuración de Firebase donde está. Comprueba en su lugar que tus reglas de seguridad están haciendo el trabajo, y mantén la API de Gemini fuera de la lista de permitidas de esa clave.
- Si encuentras un archivo JSON de
service_accounten tu frontend, trátalo como urgente. Borra la clave en la consola en vez de solo quitar el archivo, porque tu historial de versiones sigue teniendo el valor antiguo.
Si prefieres trabajar esto como una lista, la lista de seguridad de 10 minutos cubre esto junto con las otras cosas que conviene desactivar en una app recién lanzada. Y para la pregunta más amplia de qué claves van en un navegador, tenemos una guía para distinguir las claves publicables de las secretas.
Preguntas frecuentes
Alguien encontró mi clave de Google Maps en el código de la página. ¿Debo rotarla?
Restríngela primero: lleva unos cinco minutos y no rompe nada. Abre la clave en la consola de Google Cloud, pon las restricciones de aplicación en Sitios web y añade tu dominio, y después limita las restricciones de API a las APIs que usa tu app. Rotarla viene después, y solo si la clave estuvo sin restringir un tiempo y ves consumo que no has provocado tú.
¿No puedo esconder la clave para que nadie la encuentre?
No. El navegador de tu visitante tiene que enviar la clave a Google para cargar el mapa, así que todo lo que el navegador puede usar, un visitante puede leerlo. Minificar o renombrar solo frena a alguien unos segundos. Restringir la clave es el arreglo que sí funciona, y funciona tanto si alguien encuentra la clave como si no.
Mi clave está restringida a mi dominio. ¿Puede usarla alguien igualmente?
Una cabecera de referente se puede falsificar, así que alguien decidido puede enviar peticiones que digan venir de tu sitio. Lo que la restricción elimina es el caso fácil: un rastreador automático que recoge claves en páginas públicas y las usa directamente desde su propio servidor. Ese es el tráfico que produce facturas sorpresa, así que la restricción merece la pena aunque no sea un muro. Ponle además un tope de cuota diaria a la clave y tendrás un techo para lo que todo esto pueda costarte.
Firebase puso una clave de API en mi archivo de configuración. ¿Es un error?
No, y Firebase lo documenta. Una clave de API web de Firebase identifica tu proyecto en vez de autorizar el acceso, y del acceso deciden las reglas de seguridad de Firebase y App Check. Está pensada para estar en tu código. Lo único que hay que evitar es añadir la API de Gemini para desarrolladores a la lista de APIs permitidas de esa clave, porque eso convierte una clave que publicas a propósito en una que puede gastar dinero.
¿Y si encuentro un archivo con "type": "service_account" en mi app?
Esa es otra situación y es urgente. Una clave de cuenta de servicio son credenciales reales con una clave privada dentro y su sitio es un servidor. Borra la clave en la consola de Google Cloud, en IAM y administración y luego Cuentas de servicio, saca el archivo de tu frontend y revisa tu facturación y tus registros de auditoría. Borrarla solo del código no cierra la puerta, porque el valor antiguo sigue en tu historial de versiones.