Security Blog

Ver el código fuente, copiar la clave, controlarlo todo

#45

October 2, 2026 · By Marketing team

← All posts

Un investigador abrió el código fuente de la página de ClickUp, encontró una clave de API incrustada en el JavaScript y la utilizó para extraer 959 direcciones de correo electrónico y 3.165 indicadores de funciones internas en una sola petición. La clave no tenía ámbito, ni límite de frecuencia, ni caducidad.

Un investigador de seguridad accedió a clickup.com. Abrió el código fuente de la página. Encontró una clave de API incrustada en el JavaScript. La copió. Envió una petición GET.

Obtuvo 959 direcciones de correo electrónico y 3.165 indicadores de funciones internas. Empleados de Home Depot. Fortinet. Autodesk. Tenable. Rakuten. Mayo Clinic.

Una cadena. Una petición. Todo.

Cómo ocurre esto

Alguien necesitó que el frontend llamara a una API. La API exigía autenticación. Así que colocó la clave en el JavaScript. Se publica, se sigue adelante, siguiente sprint.

No se trata de un ataque sofisticado. No hay exploit, ni día cero, ni ingeniería social. Es view-source: y curl. Un navegador y un terminal. El tipo de cosa que un becario curioso hace el primer día.

La clave no tenía ámbito: podía acceder a todo lo que la API exponía. Sin límite de frecuencia: una sola petición lo devolvía todo. Sin caducidad: la clave funcionó hasta que alguien se dio cuenta. Sin segundo factor: poseer la cadena era la única barrera.

El ángulo económico

Se habla de exposición de datos. Hablemos de lo que valen estos datos.

959 direcciones de correo corporativas de empresas del Fortune 500. Es una lista de objetivos de spear-phishing por la que los actores de amenazas pagan. Nombres, cargos y el hecho de que estas empresas usan ClickUp: ese es el contexto de ingeniería social que hace que el phishing funcione.

3.165 indicadores de funciones internas. Eso es una hoja de ruta. Indica a los competidores qué está construyendo ClickUp, qué está probando y qué hay detrás de una barrera. Indica a los atacantes qué funciones están a medio construir y probablemente sean vulnerables.

No es un incidente de privacidad. Es una fuga de inteligencia empresarial.

Por qué sigue ocurriendo

Este es el cuarto incidente de credenciales en el código fuente sobre el que escribimos este mes. De la CLI de Bitwarden se extrajeron credenciales porque eran archivos de texto plano. Las variables de entorno de Vercel eran descifrables porque la marca «sensible» no estaba activada por defecto. Un desarrollador perdió 634 contraseñas de Chrome porque la clave de descifrado estaba en el mismo disco.

El patrón es siempre el mismo: una credencial existe como cadena — en un archivo, en una variable, en el código fuente de una página — y algo la lee. Ese algo cambia. El patrón, no.

Las claves de API en JavaScript son la versión más flagrante porque no requiere ningún ataque. La clave está publicada. Se entrega a cada visitante. El navegador la descarga, la renderiza y la muestra a cualquiera que haga clic derecho.

Qué debería haber sido diferente

La llamada a la API nunca debería haberse autenticado con una clave estática desde el lado del cliente. Las opciones:

  • Proxy en el backend. El frontend llama a su propio backend, que mantiene la clave en el servidor y hace de proxy de la llamada a la API. La clave nunca llega al navegador.
  • Tokens de ámbito de sesión. El frontend obtiene tras la autenticación un token de vida corta y ámbito reducido. Caduca. Solo puede hacer lo que el usuario autenticado tiene permitido hacer. No es una clave maestra.
  • Ninguna clave. Si los datos son públicos, se sirven sin autenticación. Si no lo son, no se sirven a JavaScript sin autenticar.

Incrustar una clave de API en el código del lado del cliente es dejar la llave de su casa bajo el felpudo y publicar su dirección.

El problema del ciclo de vida de las credenciales

Esta clave de ClickUp probablemente se creó una vez, se pegó en un archivo JavaScript, se hizo commit en un repositorio, se desplegó en producción y ya no se volvió a pensar en ella. Nadie la rotó. Nadie le asignó un ámbito. Nadie fijó una caducidad. Nadie supervisó a qué accedía.

Ese es el ciclo de vida de la mayoría de las claves de API en la mayoría de las organizaciones. Se crean con prisa, se pegan donde se necesitan y se olvidan. Se acumulan en bases de código, archivos de configuración, canalizaciones de CI/CD y, al parecer, en el código fuente de las páginas: cada una, una puerta que nunca se cierra.

La cuestión no es si su organización tiene una clave así. La cuestión es cuántas tiene y si se daría cuenta si alguien copiara una hoy.