API keys expuestas en el JavaScript del cliente
Todo lo que se envía al navegador — scripts inline, JS empaquetado, source maps — puede leerlo cualquiera. Las claves secretas (OpenAI, la secreta de Stripe, AWS, URLs de bases de datos) incrustadas en el código del frontend están, en la práctica, publicadas.
Qué es
Las herramientas de build insertan las variables de entorno en tiempo de compilación. Si referencias un secreto en el código del cliente, termina en el bundle de JavaScript que descarga cada visitante.
Hay una distinción crucial: las claves publicables/anónimas (pk_live de Stripe, la configuración web de Firebase) están diseñadas para ser públicas, pero las claves secretas (sk_live, claves service role, API keys de proveedores) no lo están y nunca deben llegar al navegador.
Por qué importa
Una clave de proveedor filtrada le permite a cualquiera acumular consumo en tu cuenta — facturas de LLM, cargos de SMS, gasto en la nube — o acceder a los datos que la clave autoriza.
Los atacantes rastrean bundles de JavaScript a gran escala buscando patrones de claves. Un secreto publicado suele empezar a abusarse a los pocos minutos de estar en línea.
Cómo solucionarlo
Llama a las APIs de terceros desde una ruta de servidor o un backend, nunca desde el navegador. El navegador habla con tu endpoint; tu endpoint guarda la clave.
// app/api/summarize/route.ts (server-only)
export async function POST(req: Request) {
const { text } = await req.json();
const r = await fetch("https://api.openai.com/v1/responses", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.OPENAI_API_KEY}` },
body: JSON.stringify({ model: "gpt-4o-mini", input: text }),
});
return Response.json(await r.json());
}En Next.js solo las variables con el prefijo NEXT_PUBLIC_ se exponen al navegador. Nunca pongas un secreto detrás de ese prefijo: úsalo solo para valores que pueden ser públicos sin riesgo.
Si un secreto llegó al navegador, revócalo y emite uno nuevo. Quitarlo del próximo build no invalida las copias que ya fueron extraídas.
Preguntas frecuentes
¿Mi clave publicable de Stripe (pk_live) es un problema en el frontend?
No: las claves publicables están hechas para ser públicas. El riesgo es la clave secreta (sk_live), que debe quedarse en el servidor.
¿Puedo simplemente ofuscar la clave?
No. La ofuscación se revierte trivialmente. La única solución es mantener el secreto completamente fuera del cliente.
¿Tu app está afectada?
AppSafe verifica este y docenas de problemas más en un solo escaneo gratis.
Escanear mi app gratisGuías relacionadas
Archivos .env expuestos: cómo los atacantes encuentran tus secretos
Un solo .env accesible puede entregar todo tu stack.
Los source maps en producción filtran tu código fuente
Los .map publicados entregan tu código fuente original.
Las marcas de cookies Secure, HttpOnly y SameSite
Tres marcas que evitan que te roben las cookies de sesión.