Los desarrolladores de aplicaciones móviles a menudo usan enlaces profundos para mejorar la experiencia y el compromiso del usuario al ayudar a los usuarios a navegar desde la web a su aplicación. Sin embargo, nuestras pruebas de seguridad han encontrado una vulnerabilidad fácilmente explotable cuando los enlaces profundos se usan incorrectamente con fines de autorización. Este blog explicará cómo se puede explotar esta vulnerabilidad y cómo proteger su aplicación mediante el uso de la versión más segura de los enlaces profundos. Enlaces de aplicaciones.
Resumen de enlaces profundos
Los enlaces profundos son URL que llevan a los usuarios directamente a contenido específico en una aplicación. Se pueden configurar agregando una especificación de datos (URI) dentro de un filtro de intención. Siempre que un usuario haga clic en una URL (ya sea en una vista web en una aplicación o en un navegador web en general) que coincida con el URI especificado dentro del filtro de intención, se le llevará a la actividad que lo maneja. A continuación se muestra un ejemplo que muestra cómo agregar un enlace profundo que apunte a su actividad en el archivo AndroidManifest.xml:
<activity android:name="com.nowsecure.example">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:host="login" android:scheme="nowsecure"/>
</intent-filter>
</activity>
La aplicación que maneja este enlace profundo será (1) la que el usuario está configurando para manejar dichos URI, o (2) la única aplicación instalada que puede manejarlo, o (3) una lista de aplicaciones que manejan esos URI en caso de que el usuario no haya establecido uno preferido en primer lugar.
Sin embargo, este diseño tiene un defecto. A veces, esos enlaces profundos contienen algunos datos confidenciales. Si un usuario no tiene cuidado, puede permitir que una aplicación maliciosa maneje el enlace profundo en lugar de la aplicación legítima. Afortunadamente, hay una solución para esto, App Links, que describiremos más adelante.
Descripción general de OAuth2
OAuth2 es un marco de autorización que permite que las aplicaciones obtengan acceso limitado a cuentas de usuario como GitHub, GitLab, Facebook, etc. Proporciona un mecanismo de acceso delegado al servicio que aloja la cuenta de usuario que autoriza aplicaciones de terceros, API o servidores en general para acceder a la cuenta de usuario sin tener que exponer ninguna credencial de usuario. Para acceder a los recursos protegidos, el protocolo utiliza un token de acceso, que es una cadena que representa los permisos otorgados. La siguiente figura muestra el flujo de cómo una aplicación obtiene este token de acceso:

Primero el usuario solicita acceder al servicio desde la app (cliente). Al hacerlo, la aplicación se manejará en nombre del usuario (usuario-agente). La aplicación dirigirá el servidor de recursos al servidor de autorización al incluir en su solicitud la identificación del cliente, el alcance solicitado, el estado local y un URI de redirección al que el servidor de autorización devolverá el agente de usuario una vez que se otorgue o deniegue el acceso. El servidor de autorización autentica al propietario del usuario a través del agente de usuario y, si la operación es exitosa, el servidor de autorización redirigirá al agente de usuario de regreso a la aplicación a través del URI de redirección que contiene el código de autorización. La aplicación enviará este código de autorización junto con algunos secretos predefinidos (verificador de código como se describe en PKCE) al servidor de autorización para obtener el token de acceso. Una vez obtenido el token de acceso, la aplicación puede solicitar recursos del servidor de recursos utilizando generalmente una API REST con el token de acceso dentro del encabezado de autorización HTTP(S).
Traduciendo lo anterior ahora a los términos de Android, para que la aplicación pueda recibir el Código de autorización del Servidor de autorización, deberá poder manejar el URI de redirección que se especificó en la solicitud inicial. Como describimos anteriormente, este URI contendrá el Código de autorización. Como ya habrás adivinado, para hacer eso en Android tienes que usar la versión insegura de enlaces profundos o la más segura App Links. Al usar el primero, una aplicación maliciosa instalada podría obtener el código de autorización y, si tiene acceso a los secretos, también podría obtener el token de acceso.
Aplicación móvil vulnerable real
Reuniéndolo todo, mostraremos cómo esta falla de los enlaces profundos puede conducir a una aplicación móvil maliciosa instalada para obtener tokens de acceso. La aplicación móvil se llama FastHub para GitHub y su SHA-256 es: c732c21ebacd3e8f0413edd770c11b280bc6989fe76ba825534fd3cdc995d657
. NowSecure reveló esta vulnerabilidad al desarrollador y reconoció el problema.
Para usar la aplicación móvil, debe permitir que la aplicación acceda a su cuenta de GitHub. Una de las opciones es autorizar a la aplicación para que lo haga mediante OAuth. La siguiente pantalla familiar aparecerá al hacerlo:

Lo que vemos aquí es que si autorizamos a la aplicación a acceder a nuestra cuenta de GitHub, la URI de redirección será fasthub://login
. Para verificar que este es un enlace profundo, podemos usar apktool para obtener el AndroidManifest.xml en caso de que solo tuviéramos el archivo APK. Allí encontramos la actividad. com.fastaccess.LoginActivity
con el siguiente enlace profundo que coincide con el que vimos arriba.
<activity
android:configChanges="keyboard|orientation|screenSize"
android:label="@string/app_name" android:launchMode="singleTask"
android:name="com.fastaccess.LoginActivity"
android:screenOrientation="portrait"
android:theme="@style/LoginTheme">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:host="login" android:scheme="fasthub"/>
</intent-filter>
</activity>
Ahora es el momento de ver cómo GitHub autoriza aplicaciones OAuth. Primero, la aplicación debe realizar una solicitud GET para https://github.com/login/oauth/authorize
incluyendo el client_id
, redirect_uri
y login
entre los parámetros. Si el usuario ahora acepta esa solicitud, GitHub lo redirige a la aplicación con un código temporal, el código de autorización. Después de que la aplicación recibe eso, realiza una solicitud POST para https://github.com/login/oauth/access_token
con client_id
, redirect_uri
, client_secret
y redirect_uri
entre los parámetros para obtener la access_token
. Tener el access_token
la aplicación puede acceder a la API de GitHub en nombre del usuario.
Así que si pudiéramos obtener el client_id
y client_secret
podríamos ser capaces de crear una aplicación maliciosa que tome el access_token
antes de que la aplicación legítima lo obtenga. usemos radare2 para ver si la aplicación contiene el client_id
y client_secret
codificado. Descomprimimos la app y abrimos classes.dex
con r2
. Listamos las clases/métodos y vemos si alguno de ellos contiene la palabra clave “secret”
.
[0x0070371c]> ic | grep -i secret 0x002a7f0c method 6 p Lcom/ fastaccess/data/dao/AuthModel.method.getClientSecret()Ljava/lang/String; 0x002a8094 method 14 p Lcom/ fastaccess/data/dao/AuthModel.method.setClientSecret(Ljava/lang/String;)V 0x002fd8c4 method 2 sp Lcom/ fastaccess/helper/GithubConfigHelper.method.getSecret()Ljava/lang/String;
El último parece bastante interesante. Averigüemos qué métodos GithubConfigHelper
la clase tiene.
[0x0070371c]> ic | grep GithubConfigHelper 0x0016389c [0x002fd894 - 0x002fd8ca] 54 class 1955 Lcom/ fastaccess/helper/GithubConfigHelper super: Ljava/lang/Object; 0x002fd894 method 0 sp Lcom/ fastaccess/helper/GithubConfigHelper.method.getClientId()Ljava/lang/String; 0x002fd8ac method 1 sp Lcom/ fastaccess/helper/GithubConfigHelper.method.getRedirectUrl()Ljava/lang/String; 0x002fd8c4 method 2 sp Lcom/ fastaccess/helper/GithubConfigHelper.method.getSecret()Ljava/lang/String;
Esta clase parece tener todos los datos que necesitamos para que nuestro ataque funcione. Para verificar que los datos no estén ofuscados (los valores en 0x002fd8c4 y 0x002fd894 no están ofuscados, pero nosotros los modificamos):
[0x0070371c]> s 0x002fd8c4 [0x002fd8c4]> pd2 0x002fd8c4 1a00217f const-string v0, str.e0000e7ff1000ca1bd006e000000000e1f000000 0x002fd8c8 1100 return-object v0 [0x002fd8c4]> s 0x002fd894 [0x002fd894]> pd2 0x002fd894 1a00a807 const-string v0, str.12345678901234567890 0x002fd898 1100 return-object v0
Habiendo encontrado el client_id
y client_secret
podemos crear la siguiente actividad en nuestra aplicación maliciosa. Al autorizar la aplicación legítima para acceder a nuestro perfil de GitHub, nuestra aplicación mostrará el access_token
asumiendo, por supuesto, que nuestra aplicación es la predeterminada (o está siendo seleccionada por el usuario) para manejar el fasthub://login
enlace profundo.
public class Main2Activity extends AppCompatActivity
Aquí está la entrada correspondiente en el archivo AndroidManifest.xml:
<activity
android:name=".Main2Activity"
android:label="@string/title_activity_main2"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:host="login" android:scheme="fasthub"/>
</intent-filter>
</activity>
Cómo proteger su aplicación móvil
Tener un valor secreto codificado en el archivo binario de una aplicación móvil no siempre es una buena decisión, especialmente cuando este valor no está ofuscado en absoluto. Una buena práctica de seguridad es hacer que esos valores secretos se comuniquen a la aplicación mediante un servidor back-end remoto a través de un protocolo de transmisión seguro.
Además, el uso de App Links asegurará que solo su aplicación pueda manejar cualquier URI o URL de redireccionamiento en general. Los enlaces de aplicaciones en general son la versión segura de los enlaces profundos. Para que Android maneje sus enlaces profundos como enlaces de aplicaciones, debe configurar el android:autoVerify="true"
en cualquiera de los filtros de intención de URL web de su aplicación. Además, no puede tener ningún esquema personalizado en su filtro de intenciones, sino solo http
o https
. Por último, pero no menos importante, debe incluir un archivo json con el nombre assetlinks.json
en su servidor web que se describe en el filtro de intención de URL web. Por ejemplo, si tiene el siguiente filtro de intenciones:
<activity android:name="com.nowsecure.example" android:autoVerify="true">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:host="www.nowsecure.com" android:scheme="https"/>
</intent-filter>
</activity>
Entonces el archivo json debe residir en https://www.nowsecure.com/.well-known/assetlinks.json
y ser legible por cualquier persona. El archivo json debería verse así:
[]
El nombre del paquete debe coincidir con el nombre del paquete de su aplicación y las huellas dactilares sha256_cert_fingerprints deben coincidir con las del certificado de firma de su aplicación.
Cada vez que un usuario hace clic en el enlace de una aplicación, Android se comunicará con su servidor web, tomará el assetlinks.json
y verifique que el nombre del paquete y el valor hash del certificado de firma de la aplicación coincidan con los de su aplicación. Siempre que el servidor web no se vea comprometido, solo una aplicación legítima podrá manejar este enlace de aplicación. Para más detalles por favor lea aquí.
Para reducir el riesgo en las aplicaciones móviles que desarrolla su equipo, recomendamos incorporar pruebas de seguridad de aplicaciones móviles automatizadas en la tubería de desarrollo para encontrar y corregir fallas de seguridad y privacidad más rápido. NowSecure ofrece herramientas de prueba de seguridad de aplicaciones móviles automatizadas, pruebas de penetración móvil y capacitación en seguridad de aplicaciones móviles. Obtener una manifestación hoy.