Categoria OWASP: MASVS-CODE: Code Quality
Panoramica
L'utilizzo di PendingIntent.getCreator*()
o PendingIntent.getTarget*()
per determinare se considerare attendibile il mittente di un PendingIntent crea un rischio di sfruttamento.
PendingIntent.getCreator*()
o
PendingIntent.getTarget*()
restituisce il creatore di PendingIntent, che non sempre corrisponde al mittente. Il creator potrebbe essere attendibile, ma
il mittente non deve mai essere considerato attendibile, in quanto potrebbe trattarsi di un'app dannosa
che ha acquisito l'intent in attesa di un'altra app utilizzando vari meccanismi, ad esempio:
- da
NotificationListenerService
- casi d'uso legittimi che fanno parte dell'app vulnerabile.
Un esempio di utilizzo legittimo di PendingIntent.getCreator*()
o PendingIntent.getTarget*()
sarebbe mostrare
l'icona dell'app che verrà avviata da PendingIntent.
Impatto
Affidarsi al mittente di un PendingIntent perché hai eseguito una query (e ti fidi) del creator può portare a vulnerabilità. Se un'app considera attendibile il mittente di PendingIntent in base al suo creatore e poi condivide la sua logica di autenticazione o autorizzazione, ogni volta che il mittente di PendingIntent è un'app dannosa, ciò comporterà un bypass dell'autenticazione o potenzialmente anche l'esecuzione di codice remoto in base a input non attendibili e invalidati, a seconda dell'implementazione del codice dell'applicazione vulnerabile.
Mitigazioni
Distinguere tra mittente e creator
Qualsiasi tipo di logica di autenticazione o autorizzazione eseguita durante la ricezione di un
PendingIntent non deve basarsi su presupposti relativi al
creatore di PendingIntent identificato utilizzando PendingIntent.getCreator*()
o PendingIntent.getTarget*()
.
Utilizzare metodi alternativi per convalidare i chiamanti
Se devi autenticare il chiamante, anziché utilizzare PendingIntent, devi utilizzare un servizio o un ContentProvider. Entrambi consentono di recuperare l'UID del chiamante con Binder.getCallingUid() quando ti trovi nel contesto dell'invio di un IPC in entrata. L'UID può essere interrogato in un secondo momento utilizzando PackageManager.getPackagesForUid().
Un altro approccio, disponibile dal livello API 34, consiste nell'utilizzare BroadcastReceiver.getSentFromUid() o BroadcastReceiver.getSentFromPackage() se il mittente ha attivato la condivisione dell'identità durante la trasmissione utilizzando BroadcastOptions.isShareIdentityEnabled().
Devi sempre controllare se il pacchetto chiamante ha la firma prevista, in quanto i pacchetti caricati lateralmente possono avere nomi di pacchetti che si sovrappongono a quelli del Play Store.