Cómo encontrar y validar claves y secretos incrustados en el código
Los secretos incrustados en el código son fáciles de encontrar y pueden abrir la puerta a datos sensibles o a accesos privilegiados. Esto los convierte en un excelente objetivo para los cazadores de bug bounty y para los atacantes.
Las claves secretas incrustadas en el código son un objetivo cómodo para los cazadores de bug bounty y para los atacantes. Son fáciles de detectar y pueden abrir una puerta de par en par a datos sensibles y accesos privilegiados.
Los secretos incrustados en el código han provocado en el pasado varias filtraciones de gran repercusión; entre las más notables están:
-
MyCar: MyCar es un sistema de telemática para vehículos. El fabricante dejó credenciales incrustadas en el código de sus aplicaciones móviles para Android e iOS. Esto dejó decenas de miles de coches expuestos a hackers, que podían localizarlos, identificarlos, desbloquearlos, arrancarlos o activar la alarma.
-
Uber: Un empleado de Uber publicó credenciales en texto plano dentro de código fuente que después se subió a Github. Un atacante encontró las credenciales incrustadas en GitHub y las utilizó para obtener acceso privilegiado a las instancias de Amazon AWS de Uber. El atacante exigió entonces un rescate de 100k$, que Uber pagó. La filtración de Uber supuso la exposición de la información de 57 millones de clientes, además de unos 600,000 conductores. Una vez que la historia se hizo pública, Uber pagó un acuerdo de 148M$ y tuvo que retrasar su salida a bolsa.
-
Uniguest: Uniguest ofrece quioscos (PC, iMac, tableta) disponibles en vestíbulos de hoteles (y otros lugares). Los usuarios pueden usarlos para realizar tareas sencillas, como navegar por la web o imprimir tarjetas de embarque. Las credenciales de la API estaban incrustadas en la aplicación y se utilizaron para volcar todos los datos de la base de datos en la nube de Uniguest. Los datos incluían credenciales de administrador, contraseñas de routers y de BIOS, claves de producto y otra información sensible diversa.
Los secretos incrustados en el código también son un hallazgo habitual en los informes de los cazadores de bug bounty. Si consulta cualquiera de los diversos programas de bug bounty,
encontrará muchos informes divulgados que señalan claves incrustadas en el AndroidManifest.xml, en el Info.plist o en algún archivo de recursos.
Según los permisos y el uso de la clave, estas vulnerabilidades pueden recompensarse con hasta 1k$. La severidad abarca desde la elevación de privilegios y el acceso a información sensible hasta el sobrecoste o robo de un servicio o la realización de un ataque de denegación de servicio.
¿Cómo encontrar y validar secretos?
Los secretos pueden encontrarse de forma estática o dinámica. Un enfoque estático habitual consiste en buscar patrones conocidos, por ejemplo,
buscar cadenas que coincidan con la siguiente expresión regular AIza[0-9A-Za-z\\-_]{35}:
$ app8 egrep -r 'AIza[0-9A-Za-z\\-_]{35}' .
Binary file ./resources.arsc correspondent
Binary file ./app.apk correspondent
Binary file ./classes.dex correspondent
./assets/google-services-desktop.json: "current_key": "AIzaSy....................."
En este repositorio, l4yton/RegHex, encontrará una lista de expresiones regulares que puede utilizar.
Como no todas las claves de API y secretos son malos o peligrosos, y no todos los resultados de los patrones son correctos, hay que comprobar las claves y
enumerar y verificar los permisos, roles, scopes y restricciones (más sobre esto después).
streaak publicó un repositorio, streaak/keyhacks, con comandos curl para comprobar una amplia variedad de claves.
A continuación se muestran algunos ejemplos para claves de Firebase y secretos de Facebook:
$ curl -s -X POST --header "Authorization: key=AIzaS........." --header "Content-Type:application/json" 'https://fcm.googleapis.com/fcm/send' -d '{"registration_ids":["1"]}'
<HTML>
<HEAD>
<TITLE>INVALID_KEY_TYPE</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>INVALID_KEY_TYPE</H1>
<H2>Error 401</H2>
</BODY>
</HTML>
$ curl https://graph.facebook.com/oauth/access_token\?client_id\=51XXXX\&client_secret\=0cbd4XXXXX\&redirect_uri\=\&grant_type\=client_credentials
{"access_token":"5181XXXXXXXXXXXXXX","token_type":"bearer"}%
Una vez encontrada una clave, la documentación de la API debería ser su mejor aliada para determinar qué permisos tiene y qué
tipo de acciones se pueden realizar. Tomemos como ejemplo una aplicación de Facebook: puede utilizar el endpoint https://graph.facebook.com/v8.0/{applicationId}/permissions para listar los permisos:
$ curl "https://graph.facebook.com/v8.0/51XXXXXXXX/permissions?access_token=51XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
{"data":[{"permission":"email","status":"live"},{"permission":"pages_show_list","status":"live"},{"permission":"pages_messaging","status":"live"},{"permission":"groups_show_list","status":"live"},{"permission":"pages_read_engagement","status":"live"},{"permission":"public_profile","status":"live"}]}%
Otra herramienta cómoda para la línea de comandos es detect-secret de Yelp: Yelp/detect-secrets.
La herramienta detecta un subconjunto menor de claves e implementa también la validación de algunas de ellas.
Ostorlab automatiza el proceso de encontrar y comprobar claves y secretos y cubre 53 tipos de secretos en el momento de redactar este artículo. Un agente de secretos recopila las claves que coinciden con patrones o que utilizan dinámicamente determinadas API o que se interceptan en la red. Después, el agente comprueba estas claves para confirmar si son válidas iterando sobre todos los servicios conocidos.
Esta es una captura de pantalla que muestra un ejemplo de confirmación de una clave válida y del servicio correspondiente**.

Solo en las últimas 10k aplicaciones escaneadas, hemos notificado más de 200 secretos válidos que otorgan acceso a datos altamente sensibles o a servicios críticos, como pagos o código fuente. A continuación se muestran algunas estadísticas del número de claves encontradas por servicio:
| Nombre del servicio | Cantidad |
|---|---|
| Firebase | 35/1000 |
| Google Cloud Platform | 31/1000 |
| 22/1000 | |
| 21/1000 | |
| 18/1000 | |
| AWS | 18/1000 |
| GitHub | 14/1000 |
| PayPal | 5/1000 |
| slack | 1/1000 |
¿Cómo corregirlo?
- Incrustarla es aceptable, no hay nada que hacer: la mayoría de los servicios ofrecen buenas prácticas sobre cómo usar la API o el secreto. Algunas API son aceptables si se incrustan en una aplicación. Firebase es un ejemplo:
Unlike how API keys are typically used, API keys for Firebase services are not used to control access to backend resources;
that can only be done with Firebase Security Rules.
Usually, you need to fastidiously guard API keys (for example, by using a vault service or setting the keys as environment variables);
however, API keys for Firebase services are ok to include in code or checked-in config files.
- Se recomiendan alternativas, debería cambiar: algunos servicios ofrecen alternativas más seguras que incrustar las credenciales (como Amazon y Google; ejemplo de la recomendación de AWS):
You have a mobile app. Do not embed access keys with the app, even in encrypted storage.
Instead, use Amazon Cognito to manage user identities in your app. This service lets you authenticate users using Login with Amazon, Facebook, Google, or any OpenID Connect (OIDC)–compatible identity provider.
You can then use the Amazon Cognito credentials provider to manage credentials that your app uses to make requests to AWS. For more information, see Using the Amazon Cognito Credentials Provider on the AWS Mobile Blog.
- Incrustarla es peligroso, delegue las acciones en el servidor: en algunos servicios, incrustar las claves es una invitación a que le hackeen; vea, por ejemplo, la documentación de Stripe. En estos casos, es el servidor quien debe realizar la interacción con el servicio.
Your secret API key can be used to make any API call on behalf of your account, such as creating charges or performing refunds.
Treat your secret API key as you would any other password. Grant access only to those who need it.
Ensure it is kept out of any version control system you may be using.
Control access to your key using a password manager or secrets management service.
In live mode, new secret keys are only visible the first time you access them.
After that, the Dashboard redacts the API key. When the key is revealed, you can leave a note on the Dashboard describing the location on your own systems where you’ve copied it.
If you lose your secret key, you can’t recover it from the Dashboard and must roll the key or create another one.
- Reforzar mediante la obtención remota de claves y la fijación de claves (key pinning): para los servicios que no ofrecen un servicio de autenticación por usuario y que deben incrustarse en la aplicación, se recomienda obtener la clave desde el servidor. También es una buena práctica restringir los permisos de la clave (principio de mínimo privilegio). Algunos servicios ofrecen la posibilidad de vincular (PIN) las claves a una aplicación o a un nombre de dominio. Como esta protección no es perfecta, se recomienda rotar las claves para limitar la exposición.
