
PoC et application red team pour CVE-2026-28576, une injection SQL sans permission dans l'Android Contacts Provider permettant l'exfiltration complète de la base de données des contacts.
CVE-2026-28576 est une vulnérabilité critique de contrôle d'accès dans le framework Android Contacts Provider (ContactsProvider2.queryLocal()). La faille permet à une application non privilégiée installée localement avec zéro permission déclarée d'exfiltrer l'intégralité de la base de données de contacts d'un appareil, y compris les noms complets, les numéros de téléphone, les adresses postales et les adresses e-mail.
| Attribut | Valeur |
|---|---|
| CVE ID | CVE-2026-28576 |
| GHSA ID | GHSA-ph86-9mcx-3p6r |
| Android Bug ID | A-488593616 |
| CWE | CWE-89 : Neutralisation incorrecte des éléments spéciaux utilisés dans une commande SQL (« Injection SQL ») |
| CVSS v4.0 | 10.0 (Critique) - AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H |
| Score EPSS | 0,148 % (4e percentile) |
| Publié | 17 juin 2026 |
| Composant | Android Contacts Provider (ContactsProvider2) |
| Vecteur d'attaque | Local (application sans permission) |
| Interaction utilisateur | Aucune requise |
La vulnérabilité existe dans la méthode ContactsProvider2.queryLocal() au sein du framework Android Contacts Provider (packages/providers/ContactsProvider). La méthode construit des requêtes SQL en utilisant des entrées contrôlées par l'utilisateur non assainies, permettant une injection SQL via les paramètres selection et selectionArgs transmis par ContentResolver.query().
ContentResolver.query()
→ ContactsProvider2.query()
→ ContactsProvider2.queryLocal() [VULNERABLE]
→ SQLiteQueryBuilder.buildQuery()
→ Raw SQL execution with unsanitized input
selection (String) : clause WHERE sans paramétrageselectionArgs (String[]) : arguments incorrectement échappésuri (Uri) : URI de contenu ciblant content://com.android.contacts/...READ_CONTACTS, READ_PRIVILEGED_PHONE_STATE ou autre permission dangereuseLa méthode queryLocal() traite le paramètre selection en le concaténant directement dans la clause WHERE SQL sans paramétrage approprié :
// Simplified vulnerable pattern in ContactsProvider2.java
public Cursor queryLocal(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(Tables.CONTACTS);
// VULNERABLE: selection directly interpolated into SQL
String whereClause = buildWhereClause(selection, selectionArgs);
Cursor c = qb.query(db, projection, whereClause, null, null, null, sortOrder);
return c;
}
Un attaquant forge un paramètre selection malveillant tel que :
"1=1) UNION SELECT _id, display_name, phone_number, email_address, postal_address FROM raw_contacts--"
Cela contourne la logique de requête prévue et extrait tous les champs de contact.
graph TD
A[Malicious App Installed] --> B[Request ContentResolver.query]
B --> C[Craft SQL Injection Payload]
C --> D[Target content://com.android.contacts/data]
D --> E[ContactsProvider2.queryLocal]
E --> F[Unsanitized selection parameter]
F --> G[SQL Injection Executed]
G --> H[Full Contacts DB Returned]
H --> I[Exfiltrate via Network/Logs]UNION/UPDATE| Version Android | Statut |
|---|---|
| Android 14 (U) | Vulnérable |
| Android 15 (V) | Vulnérable |
| Android 16 (W) | Vulnérable |
| Android 17 (juin 2026+) | Corrigé |
rule Android_ContactsProvider_SQLi_CVE_2026_28576 {
meta:
description = "Detects SQL injection payloads targeting ContactsProvider"
cve = "CVE-2026-28576"
severity = "critical"
strings:
$s1 = "content://com.android.contacts" nocase
$s2 = "UNION SELECT" nocase
$s3 = "raw_contacts" nocase
$s4 = "data1" nocase
$s5 = "1=1" nocase
condition:
$s1 and 2 of ($s2, $s3, $s4, $s5)
}
alert http any any -> any any (
msg:"CVE-2026-28576 Contacts Exfiltration";
flow:established,to_server;
content:"contacts";
http.uri;
pcre:"/UNION.*SELECT.*raw_contacts/i";
classtype:web-application-attack;
sid:202628576;
rev:1;
)
ContentResolver.query() via une politique SELinuxContactsProvider pour détecter des paramètres selection anormauxcontent://com.android.contacts sans la permission READ_CONTACTSDocument généré pour le dépôt de recherche CVE-2026-28576 Dernière mise à jour : septembre 2025
| Catégorie de données | Champs exposés |
|---|
| Identité | display_name, phonetic_name, nickname, company, title |
| Numéros de téléphone | number, type (mobile, domicile, travail, fax, etc.), label |
| Adresses e-mail | address, type (domicile, travail, autre), label |
| Adresses postales | street, city, region, postcode, country, type |
| Données structurées | mimetype, data1–data15, sync1–sync4 |
| Métadonnées | contact_id, raw_contact_id, version, dirty, deleted |