Cómo proteger las opciones para desarrolladores

Según el Documento de definición de compatibilidad de Android, los OEMs deben proporcionar una forma de habilitar el desarrollo de apps. Sin embargo, proporcionar opciones para desarrolladores similares a las de dispositivos móviles en los automóviles los deja vulnerables a ataques. Ahora, un OEM puede restringir el acceso a las opciones para desarrolladores mediante un mecanismo de token criptográfico autenticado. En particular, un OEM puede hacer lo siguiente:

  • Especificar restricciones predeterminadas antes del primer inicio
  • Autorizar a los desarrolladores de forma segura con tokens criptográficos, si lo prefieres
  • Aplicar cambios en las restricciones una vez que se autentica y autoriza a un desarrollador

En esta página, se describe una implementación de referencia que consta de una app de controlador de restricciones de depuración y un extremo emisor de tokens remoto.

Terminología

Además de terminología, en esta página, se usan los siguientes términos:

  • Firma web JSON (JWS), definida en RFC 7515
  • Instituto Nacional de Normas y Tecnología (NIST)

Diseño

Los OEMs pueden autorizar a los desarrolladores con tokens de firma web JSON (JWS) (RFC7515). En la implementación de referencia, los OEMs emiten tokens de acceso, y la app de controlador de restricciones los consume. Los tokens de acceso están diseñados para resistir ataques de reproducción y tokens falsificados.

Figura 1: Diseño

Integración y configuración

Los OEMs deben especificar restricciones predeterminadas en el primer inicio. Para ello, usan varias superposiciones de recursos estáticos para anular los valores predeterminados en el framework de AOSP.

Las restricciones predeterminadas para el usuario del sistema sin interfaz gráfica se pueden configurar con la cadena config_defaultFirstUserRestrictions en frameworks/base/core/res/res/values/config.xml, por ejemplo:

<!-- User restrictions set when the first user is created.
         Note: Also update appropriate overlay files. -->
    <string-array translatable="false" name="config_defaultFirstUserRestrictions">
        <item>no_debugging_features</item>
        <item>no_install_unknown_sources</item>
        <item>no_install_unknown_sources_globally</item>
    </string-array>

Las restricciones predeterminadas para conductores, pasajeros y usuarios invitados se pueden configurar en frameworks/base/core/res/res/xml/config_user_types.xml. Un OEM puede superponer estas cadenas para establecer las restricciones predeterminadas en cada tipo de usuario, respectivamente, por ejemplo:

<user-types>
    <full-type name="android.os.usertype.full.SECONDARY" >
        <default-restrictions
            no_debugging_features="true"
            no_install_unknown_sources="true"/>
    </full-type>
    <full-type name="android.os.usertype.full.GUEST" >
        <default-restrictions
            no_debugging_features="true"
            no_install_unknown_sources="true"/>
    </full-type>
</user-types>

Controlador de preferencias de número de compilación

En AAOS, la interacción del usuario con la fila de preferencias de Número de compilación en Configuración se controla con BuildNumberPreferenceController.java, que se encuentra en packages/apps/Car/Settings/src/com/android/car/settings/system/BuildNumberPreferenceController.java.

Cuando se establece la restricción de usuario no_debugging_features (UserManager.DISALLOW_DEBUGGING_FEATURES), BuildNumberPreferenceController suprime la cuenta regresiva para desarrolladores en las compilaciones de producción (user) cuando se presiona:

@Override
protected boolean handlePreferenceClicked(Preference preference) {
    if (DevelopmentSettingsUtil.isDevelopmentSettingsEnabled(getContext())) {
        return true;
    }

    // Enforce restriction on production (user) builds
    if (Build.IS_USER && mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES)) {
        showToast(R.string.dev_access_blocked_toast);
        return true;
    }

    mDevHitCountdown--;
    if (mDevHitCountdown == 0) {
        DevelopmentSettingsUtil.setDevelopmentSettingsEnabled(getContext(), true);
        showToast(R.string.show_dev_on);
    }
    return true;
}

El uso de Build.IS_USER garantiza que las compilaciones de producción apliquen estrictamente el bloqueo de seguridad, mientras que los equipos de ingeniería internos en las compilaciones userdebug aún pueden acceder a las opciones para desarrolladores con el gesto de 7 toques para realizar pruebas sin anulaciones manuales de la interfaz de línea de comandos (CLI).

Controlador de restricciones de depuración

Se proporciona una implementación de referencia del controlador de restricciones de depuración (DRC) en AOSP en packages/apps/Car/DebuggingRestrictionController.

El DRC permite que los OEMs levanten de forma dinámica y temporal la restricción no_debugging_features en los vehículos de producción para técnicos de servicio y desarrolladores autorizados. En lugar de dejar las herramientas de depuración abiertas de forma permanente o requerir que se vuelvan a flashear los firmwares, la app de DRC en el vehículo le solicita al usuario que se autentique con el backend del OEM y envíe un token de acceso firmado criptográficamente para habilitar adb y las opciones para desarrolladores para una sesión de diagnóstico finita.

La implementación de referencia del DRC consta de dos componentes principales:

  • App cliente de DRC en el vehículo (app/): Una app del sistema con privilegios (que tiene el permiso MANAGE_USERS) en la consola central que autentica a los desarrolladores, valida la firma del certificado X.509, el nombre de host, el nonce y el vencimiento de los tokens JWS entrantes, y activa o desactiva de forma dinámica la restricción no_debugging_features con UserManager.
  • Emisor de tokens en la nube (server/): Un servicio web de backend (que se puede implementar como Firebase Cloud Functions) que autentica las credenciales del desarrollador y emite tokens de acceso JWS RS256 firmados criptográficamente con un período de vencimiento finito.

Para obtener instrucciones de configuración completas, herramientas de generación de certificados y pasos de implementación, consulta la guía de integración del controlador de restricciones de depuración.

Pruebas

Google recomienda que los OEMs comiencen con la implementación de referencia y, luego, desarrollen a partir de ella.

  1. Después de configurar las restricciones en los archivos de superposición, compila AAOS y valida los flujos definidos. Usa la app de referencia y el servicio local habilitado para JWS para verificar tu configuración de acceso.
  2. Opcional: Configura el sistema para que use tu servicio en la nube habilitado para JWS. Verifica que observes el flujo esperado en tu servicio de backend.