LocationNetworkDevice & system
Wi-Fi Networks on Android: WifiConfigStore.xml
Saved Wi-Fi networks on Android: WifiConfigStore.xml paths per version, SSIDs, keys, creator app, per-network randomized MAC, connection status and caveats.
- Location
- /data/misc/apexdata/com.android.wifi/WifiConfigStore.xml (Android 11+), /data/misc/wifi/WifiConfigStore.xml (Android 8 to 10)
- Proves
- Which Wi-Fi networks the device saved, whether it ever connected to them, who added them (user in Settings or an app), their security type and key, and the MAC address the phone used on each
- Timestamps
- Few per-network times: some builds store creation or update strings without a year, newer builds may add connection times; rely on file system times and other artifacts
- Access
- Full file system (root, exploit or agent); system device-encrypted storage, so readable in BFU by a privileged extraction. Logical and bugreport: saved networks via dumpsys wifi (keys masked). Not in ADB backup.
- Retention
- Until the user forgets the network, the configuring app removes its suggestion, or factory reset
- Collection
- Full file system extraction, adb shell dumpsys wifi, adb bugreport
Tools
Compare all toolsWhat it is
Android's Wi-Fi service persists the networks a user has saved in an XML store named WifiConfigStore.xml. Every network entered in Settings, joined through a QR code, restored from a Google backup or added by an app through the Wi-Fi APIs has a <Network> element with its SSID, security type, credentials and status. It is a location artifact as much as a network one: a saved SSID such as a hotel, an employer or a friend's router places the phone there at least once.
Since Android 11 the Wi-Fi stack is an updatable Mainline module (APEX), which is why its files moved to an apexdata folder.
Where it lives
| Android | Main (shared) store | Other files |
|---|---|---|
| 8 to 10 | /data/misc/wifi/WifiConfigStore.xml | /data/misc/wifi/softap.conf (hotspot); per-user store in /data/misc_ce/<user>/wifi/ |
| 11 to 16 | /data/misc/apexdata/com.android.wifi/WifiConfigStore.xml | WifiConfigStoreSoftAp.xml (hotspot) in the same folder; per-user store in /data/misc_ce/<user>/apexdata/com.android.wifi/, e.g. WifiConfigStoreNetworkSuggestions.xml for networks suggested by apps |
Before Android 8, saved networks lived in wpa_supplicant.conf; that file is not used on the versions covered here. On most builds WifiConfigStore.xml is plain XML. Several Android 12+ system files use Android Binary XML (ABX): if the file starts with the bytes ABX, convert it first.
What it proves
- The SSIDs saved on the device, including hidden networks (
HiddenSSID), and their security (open, WPA2-PSK, WPA3-SAE, enterprise EAP). - Whether the phone ever connected successfully (
HasEverConnectedin the network status block). - Who created and last modified each entry (
CreatorName/CreatorUid,LastUpdateName/LastUpdateUid):com.android.settingsfor the user, another package for an app, the system for restored networks. - The randomized MAC address the phone presents to that network (
RandomizedMacAddress), plus the MAC randomization setting. - The pre-shared key, in clear on many builds (or as encrypted data on builds that protect it with the Keystore).
It does not tell you when or how often the phone was on a network, and a saved network may come from a cloud restore of an older phone.
Key fields
| Element or attribute | Meaning |
|---|---|
ConfigKey | SSID plus security type, e.g. "CafeGuest"NONE, "HomeNet"WPA_PSK |
SSID, HiddenSSID | Network name (quoted), hidden flag |
PreSharedKey / WEPKeys / EncryptedData | Credentials, clear or encrypted depending on build |
CreatorName, CreatorUid, LastUpdateName, LastUpdateUid | Package and UID that added or changed the entry |
RandomizedMacAddress, MacRandomizationSetting | Per-network MAC used by the phone, randomization mode |
NetworkSelectionStatus, HasEverConnected, ConnectChoice | Status block: enabled or disabled (and why), ever connected, user preference over another network |
IpConfiguration | Static IP, proxy settings |
EnterpriseConfiguration | EAP method, identity, certificates for 802.1X networks |
Element names and the store Version change between releases; read the file before writing an extraction script.
Timestamps
The store has few reliable per-network timestamps. Some Android 8 and 9 builds wrote CreationTime and UpdateTime strings in a month-day-time format without a year; later builds dropped them, and some recent builds record connection-related times in the status block. Treat any of them as build-specific. The file's own modification time only shows the last change to any network. To date an association, correlate with usagestats screen events, bugreport Wi-Fi logs, photo EXIF, or the access point's logs.
xmllint --xpath '//Network/WifiConfiguration/string[@name="SSID"]/text()' WifiConfigStore.xml
python3 - <<'PY'
import xml.etree.ElementTree as ET
for net in ET.parse("WifiConfigStore.xml").iter("Network"):
cfg = net.find("WifiConfiguration")
get = lambda n: (cfg.find(f"*[@name='{n}']").text if cfg.find(f"*[@name='{n}']") is not None else None)
status = net.find("NetworkStatus")
ever = status.find("*[@name='HasEverConnected']") if status is not None else None
print(get("SSID"), get("CreatorName"), get("RandomizedMacAddress"),
ever.get("value") if ever is not None else None)
PY
Retention
A network stays until the user taps Forget, the app that suggested it withdraws the suggestion or is uninstalled, a device policy removes it, or the phone is factory reset. Networks can come back through a Google backup restore on a new phone, keeping their original SSID but a new creator context.
Collection
- Full file system extraction: copy the whole
apexdata/com.android.wififolder (or/data/misc/wifion 8 to 10) and the per-user store. The main store sits in system device-encrypted storage, since the phone joins Wi-Fi before the user unlocks, so a privileged extraction reaches it even in BFU. - Logical:
adb shell dumpsys wifilists configured networks, recent scan results and a connection log without root; keys are masked and the output format varies by build. - Bugreport: includes the Wi-Fi service dump with recent connection events.
Parsing
ALEAPP reports saved Wi-Fi profiles and hotspot configuration. For manual work, xmllint or Python ElementTree are enough on plain XML; convert ABX first with abx2xml on a device running Android 12 or later, or with ccl_abx offline.
Investigator tips
- The
RandomizedMacAddressfor a network is stable for that SSID on most builds: search router, DHCP, captive portal or enterprise Wi-Fi logs for it to prove presence and get times. - A
CreatorNamethat is not Settings or the system points at an app that configured Wi-Fi; check it in installed packages. Stalkerware and MDM agents do this. - Networks with
HasEverConnectedfalse were saved but never joined, often restored from another device. - Hotspot configuration (
WifiConfigStoreSoftAp.xml) shows the phone's own tethering SSID and passphrase, which other devices may have saved. - Visits to captive portals often appear in Chrome history right after an association: a useful time anchor.