← Blog ·

Apps de e-commerce: la clave de tu pasarela de pago no debería viajar en el APK

Descargas el APK de una app de ecommerce, lo pasas por apktool o jadx, y buscas la cadena sk_live_. En muchos casos aparece. La clave secreta de Stripe, de Mercado Pago o de la pasarela que sea, dentro del binario que cualquiera puede instalar en su móvil y desmontar en un rato.

No hace falta ser un atacante sofisticado. Un strings sobre el APK descomprimido y una búsqueda con grep bastan para encontrar credenciales que nunca deberían haber salido del backend. Y en apps de ecommerce el impacto no es teórico: esa clave puede permitir crear cargos, emitir reembolsos o leer datos de transacciones según los permisos que tenga.

Este artículo es para dos perfiles distintos que se topan con el mismo problema: el desarrollador indie que está construyendo la app ahora mismo y decide dónde meter la clave, y el equipo enterprise que ya tiene la app en producción y acaba de descubrir (o teme descubrir) que la clave está hardcodeada.

Por qué la clave termina en el APK

Casi nunca es negligencia pura. Es el camino de menor resistencia:

  • El equipo necesita que la app hable con la pasarela de pago y la forma más rápida es meter la API key en una variable de entorno de build, que Expo o React Native empaquetan tal cual en el bundle.
  • Un asistente de IA genera el código de integración con la pasarela y coloca la clave directamente en el archivo de configuración, porque es lo que ve en la documentación de ejemplo.
  • Nadie revisa el APK final buscando strings sensibles antes de publicarlo en la Play Store o la App Store.

En la era del código generado por IA esto se ha vuelto más frecuente, no menos: el asistente resuelve el "que funcione" y rara vez pregunta dónde debería vivir el secreto. Si quieres el contexto completo de por qué esto es la causa número uno de exposición de credenciales hoy, lo tratamos en /ai-security.

El patrón correcto: el secreto no vive en el binario

La solución no es "ofuscar" la clave ni moverla a un archivo .env que igualmente se empaqueta. Es que el binario nunca contenga el secreto en texto plano, ni siquiera cifrado con una clave que también viaja en el APK (eso solo añade un paso al mismo problema).

El patrón que soporta Koove hoy es este: el secreto se guarda cifrado en el servidor (que nunca ve el texto plano, solo ciphertext) y se descifra únicamente en dispositivos que pasan attestation de hardware — App Attest en iPhone, Play Integrity en Android — más biometría del usuario. Sin dispositivo atestiguado, no hay descifrado.

Si estás construyendo la app ahora

Guardas la clave una sola vez, desde tu máquina o desde el pipeline de CI, con la CLI:

koove set STRIPE_SECRET_KEY sk_live_51abc... --env prod
koove list --env prod

En el código de la app, tanto si lo escribes tú como si lo genera un asistente de IA, ya no hay ninguna clave literal. Solo un nombre:

import { KooveClient } from '@koove/sdk';

const koove = new KooveClient({
  apiUrl: 'https://api.koove.io',
  appId: process.env.KOOVE_APP_ID,
  appToken: process.env.KOOVE_APP_TOKEN,
});

await koove.init(); // attestation (App Attest / Play Integrity) + registro + biometría

// tu backend entrega el envelope cifrado correspondiente a STRIPE_SECRET_KEY
const stripeKey = await koove.decryptSecret(envelope);

stripeKey solo existe en memoria del dispositivo, después de que el SDK haya verificado attestation y biometría. En ningún momento se compila dentro del APK ni del IPA. Requiere un dev build de Expo/React Native (no funciona en Expo Go), y toda la lógica está documentada en /docs/sdk.

Si ya estás en producción

Si el equipo enterprise ya tiene la clave hardcodeada y lo descubre — por una auditoría, un pentest, o porque alguien la encontró en un APK filtrado — el problema no se resuelve solo migrando el código nuevo. Hay que asumir que la clave actual está potencialmente comprometida.

El proceso realista:

  1. Rotar la clave en el panel de la pasarela de pago (Stripe, Mercado Pago, la que sea) — esto es responsabilidad del proveedor, no de Koove.
  2. Guardar la nueva clave en Koove: koove set STRIPE_SECRET_KEY sk_live_nueva... --env prod.
  3. Sacar toda referencia literal del código y sustituirla por decryptSecret.
  4. Publicar una nueva versión del binario. Las versiones antiguas con la clave hardcodeada siguen circulando en dispositivos que no se han actualizado — eso no se puede revertir.
  5. Gestionar qué dispositivos pueden descifrar con koove devices, koove device-approve y koove device-revoke según tu política de acceso.

Lo que Koove no puede hacer (y hay que decirlo claro)

Si un dispositivo atestiguado y con biometría válida ya descifró la clave y alguien extrajo ese valor en tiempo de ejecución — por ejemplo con un hook en un dispositivo con jailbreak que logró pasar por otro medio, o simplemente porque el usuario legítimo del dispositivo hizo algo indebido con el valor una vez en memoria — revocar ese dispositivo después no deshace esa extracción. device-revoke corta el acceso futuro, no borra lo que ya salió.

Tampoco es criptografía con forward secrecy tipo Signal: es un esquema envelope con X25519 + AES-256-GCM y HKDF-SHA256, sobre primitivas abiertas en @koove/crypto, no una capa de mensajería con ratchet. Lo que sí evita, de forma verificada en hardware físico en ambas plataformas, es que la clave exista en texto plano dentro del binario que cualquiera puede descompilar sin necesidad de tocar el dispositivo del usuario final. La arquitectura completa está en /security.

Por dónde empezar

Si estás construyendo la app: integra la CLI y el SDK desde el primer sprint, antes de que la clave de la pasarela llegue a tocar el repositorio.

Si ya estás en producción: trata esto como lo que es, un incidente de seguridad en curso mientras la clave siga en el APK publicado, y prioriza la rotación y migración.

En ambos casos, echa un vistazo a los planes en /plans y crea tu cuenta en /register para empezar a mover las claves de tu app de ecommerce fuera del binario.

Código generado por IA

Tu IA escribe el código. ¿Quién guarda los secretos?

El fallo de seguridad más común en apps generadas con IA son las credenciales expuestas. Con Koove, tu propio asistente guarda cada token desde la CLI — cifrado en tu máquina, nunca en el código ni en el repo.