Todas las guías
Severidad CríticaSecretos expuestos

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

Mantén los secretos en el servidor

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());
}
Usa el prefijo NEXT_PUBLIC_ con intención

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.

Rota las claves filtradas

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 gratis