Esta información está dirigida a desarrolladores cuyas apps contengan la vulnerabilidad de Intent Redirection.
Novedades
Una o más de tus apps contienen un problema relacionado con Intent Redirection, lo que puede permitir que apps maliciosas accedan a archivos o componentes privados de la app. Revisa los pasos detallados que aparecen a continuación para solucionar el problema. Después de los plazos que aparecen en Play Console, se eliminarán de Google Play todas las apps que contengan vulnerabilidades de seguridad no resueltas.
Acción necesaria
- Accede a tu cuenta de Play Console y ve a la sección "Alertas" para observar qué apps están afectadas y los plazos para resolver los problemas.
- Actualiza las apps afectadas. Para ello, sigue los pasos que se destacan a continuación.
- Envía las versiones actualizadas de las apps afectadas.
Una vez que las hayas reenviado, revisaremos tu app nuevamente. Este proceso puede demorar varias horas. Si la app pasa la revisión y se publica sin problemas, no se requerirá ninguna otra acción. Si la app no pasa la revisión, no se publicará la nueva versión, y recibirás una notificación por correo electrónico.
Detalles adicionales
El uso de intents no confiables para iniciar un componente (por ejemplo, mediante una llamada a startActivity) o mostrar datos (por ejemplo, mediante una llamada a setResult), es peligroso y puede permitir que aplicaciones maliciosas causen los siguientes problemas:
- Robar archivos o datos del sistema sensibles (como mensajes SMS) de tu app
- Iniciar los componentes privados de tu app con argumentos contaminados
Es importante que tu app no llame a startActivity, startService, sendBroadcast o setResult mediante intents no confiables sin antes validarlos o depurarlos.
Te recomendamos que evites esta vulnerabilidad de cualquiera de las siguientes maneras:
Opción 1: Convierte en privado el componente de la app afectado desde donde se redirecciona el intent extraído.
Si el componente afectado no necesita recibir intents de otras apps, puedes convertirlo en privado. Para ello, debes configurar android:exported como falso en tu manifiesto.
Opción 2: Asegúrate de que el intent extraído provenga de una fuente confiable.
Puedes usar métodos como getCallingActivity para verificar que la actividad de origen sea de confianza. Por ejemplo:
// verifica si la actividad de origen es de un paquete de confianza
if (getCallingActivity().getPackageName().equals(“known”)) {
Intent intent = getIntent();
// extrae el intent anidado
Intent forward = (Intent) intent.getParcelableExtra(“key”);
// redirecciona el intent anidado
startActivity(forward);
}
Nota:
- No es suficiente verificar si getCallingActivity() devuelve un valor no nulo para prevenir la vulnerabilidad. Las apps maliciosas pueden proporcionar un valor nulo para esta función.
- En el caso de la SMS Retriever Auth de los Servicios de Google Play, proteger un receptor de emisión con SEND_PERMISSION garantizará que el intent provenga de los Servicios de Play.
Opción 3: Asegúrate de que el intent de redireccionamiento no sea dañino.
Debes comprobar lo siguiente:
- No se enviará el intent a ninguno de los componentes privados de tu app.
- No se enviará el intent al componente de una app externa. Si el redireccionamiento tiene como fin orientarse a una app externa, asegúrate de que el intent no conceda un permiso de URI a uno de los proveedores privados de contenido ni a los datos del sistema de la app.
Las apps pueden comprobar el componente que se usará para manejar el intent antes de redireccionarlo con métodos como resolveActivity. Por ejemplo:
Intent intent = getIntent();
// extrae el intent anidado
Intent forward = (Intent) intent.getParcelableExtra(“key”);
// obtiene el nombre del componente
ComponentName name = forward.resolveActivity(getPackageManager());
// verifica que el nombre del paquete y el nombre de la clase sean los deseados
if (name.getPackageName().equals(“safe_package”) &&
name.getClassName().equals(“safe_class”)) {
// redirecciona el intent anidado
startActivity(forward);
}
Las apps pueden verificar si un intent otorga un permiso de URI con métodos como getFlags. Por ejemplo:
// extrae el intent anidado
Intent forward = (Intent) intent.getParcelableExtra(“key”);
// obtiene las marcas
int flags = forward.getFlags();
// comprueba que el intent anidado no otorgue permisos de URI
if ((flags & Intent.FLAG_GRANT_READ_URI_PERMISSION == 0) &&
(flags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION == 0)) {
// redirecciona el intent anidado
startActivity(forward);
}
Mediante removeFlags, las apps también pueden quitar permisos de URI otorgados. Por ejemplo:
// Intent no confiable
Intent intent = getIntent();
// quita los permisos de URI otorgados del intent no confiable
intent.removeFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.removeFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
// pasa el intent no confiable
setResult(intent);
Cómo comprender las alertas y elegir una opción de prevención
La alerta de Play Console informa dónde la app llama a startActivity, startActivityForResult, startService, sendBroadcast o setResult mediante un intent no confiable. Para comprender mejor qué opción de prevención es la más adecuada, regresa y observa los llamadores de métodos para ver dónde se origina el intent no confiable. Por ejemplo, en el caso de la opción 1, realiza un seguimiento para determinar qué componente debe ser privado.
Estamos aquí para ayudarte
Si tienes preguntas técnicas sobre la vulnerabilidad, puedes publicarlas en Stack Overflow con la etiqueta "android-security". Si necesitas aclaración sobre los pasos que debes seguir para resolver el problema, puedes comunicarte con nuestro equipo de asistencia para desarrolladores.